upload-pack: make want_obj not global

Because upload_pack_v2() can be invoked multiple times in the same process, the static variable want_obj may not be empty when it is invoked. To make further analysis of this situation easier, make the variable local; analysis will be done in a subsequent patch. The new local variable in upload_pack_v2() is static to preserve existing behavior; this is not necessary in upload_pack() because upload_pack() is only invoked once per process. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Oct 18, 2018 at 13:43 UTC 1d1243fe6328db9b2b045afee9357ab7c6c515f1
1 file changed +66 -50
upload-pack.c
+66 -50
@@ -53,7 +53,6 @@ static int no_progress, daemon_mode;
53 #define ALLOW_ANY_SHA1 07
54 static unsigned int allow_unadvertised_object_request;
55 static int shallow_nr;
56 -static struct object_array want_obj;
56 static struct object_array extra_edge_obj;
57 static unsigned int timeout;
58 static int keepalive = 5;
@@ -99,7 +98,8 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
98 return 0;
99 }
100
102 -static void create_pack_file(const struct object_array *have_obj)
101 +static void create_pack_file(const struct object_array *have_obj,
102 + const struct object_array *want_obj)
103 {
104 struct child_process pack_objects = CHILD_PROCESS_INIT;
105 char data[8193], progress[128];
@@ -160,9 +160,9 @@ static void create_pack_file(const struct object_array *have_obj)
160 if (shallow_nr)
161 for_each_commit_graft(write_one_shallow, pipe_fd);
162
163 - for (i = 0; i < want_obj.nr; i++)
163 + for (i = 0; i < want_obj->nr; i++)
164 fprintf(pipe_fd, "%s\n",
165 - oid_to_hex(&want_obj.objects[i].item->oid));
165 + oid_to_hex(&want_obj->objects[i].item->oid));
166 fprintf(pipe_fd, "--not\n");
167 for (i = 0; i < have_obj->nr; i++)
168 fprintf(pipe_fd, "%s\n",
@@ -338,19 +338,21 @@ static int got_oid(const char *hex, struct object_id *oid,
338 return 0;
339 }
340
341 -static int ok_to_give_up(const struct object_array *have_obj)
341 +static int ok_to_give_up(const struct object_array *have_obj,
342 + struct object_array *want_obj)
343 {
344 uint32_t min_generation = GENERATION_NUMBER_ZERO;
345
346 if (!have_obj->nr)
347 return 0;
348
348 - return can_all_from_reach_with_flag(&want_obj, THEY_HAVE,
349 + return can_all_from_reach_with_flag(want_obj, THEY_HAVE,
350 COMMON_KNOWN, oldest_have,
351 min_generation);
352 }
353
353 -static int get_common_commits(struct object_array *have_obj)
354 +static int get_common_commits(struct object_array *have_obj,
355 + struct object_array *want_obj)
356 {
357 struct object_id oid;
358 char last_hex[GIT_MAX_HEXSZ + 1];
@@ -368,7 +370,7 @@ static int get_common_commits(struct object_array *have_obj)
370
371 if (!line) {
372 if (multi_ack == 2 && got_common
371 - && !got_other && ok_to_give_up(have_obj)) {
373 + && !got_other && ok_to_give_up(have_obj, want_obj)) {
374 sent_ready = 1;
375 packet_write_fmt(1, "ACK %s ready\n", last_hex);
376 }
@@ -389,7 +391,7 @@ static int get_common_commits(struct object_array *have_obj)
391 switch (got_oid(arg, &oid, have_obj)) {
392 case -1: /* they have what we do not */
393 got_other = 1;
392 - if (multi_ack && ok_to_give_up(have_obj)) {
394 + if (multi_ack && ok_to_give_up(have_obj, want_obj)) {
395 const char *hex = oid_to_hex(&oid);
396 if (multi_ack == 2) {
397 sent_ready = 1;
@@ -582,7 +584,7 @@ error:
584 return 1;
585 }
586
585 -static void check_non_tip(void)
587 +static void check_non_tip(struct object_array *want_obj)
588 {
589 int i;
590
@@ -593,14 +595,14 @@ static void check_non_tip(void)
595 */
596 if (!stateless_rpc && !(allow_unadvertised_object_request & ALLOW_REACHABLE_SHA1))
597 goto error;
596 - if (!has_unreachable(&want_obj))
598 + if (!has_unreachable(want_obj))
599 /* All the non-tip ones are ancestors of what we advertised */
600 return;
601
602 error:
603 /* Pick one of them (we know there at least is one) */
602 - for (i = 0; i < want_obj.nr; i++) {
603 - struct object *o = want_obj.objects[i].item;
604 + for (i = 0; i < want_obj->nr; i++) {
605 + struct object *o = want_obj->objects[i].item;
606 if (!is_our_ref(o))
607 die("git upload-pack: not our ref %s",
608 oid_to_hex(&o->oid));
@@ -621,7 +623,8 @@ static void send_shallow(struct commit_list *result)
623 }
624 }
625
624 -static void send_unshallow(const struct object_array *shallows)
626 +static void send_unshallow(const struct object_array *shallows,
627 + struct object_array *want_obj)
628 {
629 int i;
630
@@ -645,7 +648,7 @@ static void send_unshallow(const struct object_array *shallows)
648 parents = ((struct commit *)object)->parents;
649 while (parents) {
650 add_object_array(&parents->item->object,
648 - NULL, &want_obj);
651 + NULL, want_obj);
652 parents = parents->next;
653 }
654 add_object_array(object, NULL, &extra_edge_obj);
@@ -656,7 +659,7 @@ static void send_unshallow(const struct object_array *shallows)
659 }
660
661 static void deepen(int depth, int deepen_relative,
659 - struct object_array *shallows)
662 + struct object_array *shallows, struct object_array *want_obj)
663 {
664 if (depth == INFINITE_DEPTH && !is_repository_shallow(the_repository)) {
665 int i;
@@ -679,17 +682,18 @@ static void deepen(int depth, int deepen_relative,
682 } else {
683 struct commit_list *result;
684
682 - result = get_shallow_commits(&want_obj, depth,
685 + result = get_shallow_commits(want_obj, depth,
686 SHALLOW, NOT_SHALLOW);
687 send_shallow(result);
688 free_commit_list(result);
689 }
690
688 - send_unshallow(shallows);
691 + send_unshallow(shallows, want_obj);
692 }
693
694 static void deepen_by_rev_list(int ac, const char **av,
692 - struct object_array *shallows)
695 + struct object_array *shallows,
696 + struct object_array *want_obj)
697 {
698 struct commit_list *result;
699
@@ -697,21 +701,22 @@ static void deepen_by_rev_list(int ac, const char **av,
701 result = get_shallow_commits_by_rev_list(ac, av, SHALLOW, NOT_SHALLOW);
702 send_shallow(result);
703 free_commit_list(result);
700 - send_unshallow(shallows);
704 + send_unshallow(shallows, want_obj);
705 }
706
707 /* Returns 1 if a shallow list is sent or 0 otherwise */
708 static int send_shallow_list(int depth, int deepen_rev_list,
709 timestamp_t deepen_since,
710 struct string_list *deepen_not,
707 - struct object_array *shallows)
711 + struct object_array *shallows,
712 + struct object_array *want_obj)
713 {
714 int ret = 0;
715
716 if (depth > 0 && deepen_rev_list)
717 die("git upload-pack: deepen and deepen-since (or deepen-not) cannot be used together");
718 if (depth > 0) {
714 - deepen(depth, deepen_relative, shallows);
719 + deepen(depth, deepen_relative, shallows, want_obj);
720 ret = 1;
721 } else if (deepen_rev_list) {
722 struct argv_array av = ARGV_ARRAY_INIT;
@@ -728,11 +733,11 @@ static int send_shallow_list(int depth, int deepen_rev_list,
733 }
734 argv_array_push(&av, "--not");
735 }
731 - for (i = 0; i < want_obj.nr; i++) {
732 - struct object *o = want_obj.objects[i].item;
736 + for (i = 0; i < want_obj->nr; i++) {
737 + struct object *o = want_obj->objects[i].item;
738 argv_array_push(&av, oid_to_hex(&o->oid));
739 }
735 - deepen_by_rev_list(av.argc, av.argv, shallows);
740 + deepen_by_rev_list(av.argc, av.argv, shallows, want_obj);
741 argv_array_clear(&av);
742 ret = 1;
743 } else {
@@ -817,7 +822,7 @@ static int process_deepen_not(const char *line, struct string_list *deepen_not,
822 return 0;
823 }
824
820 -static void receive_needs(void)
825 +static void receive_needs(struct object_array *want_obj)
826 {
827 struct object_array shallows = OBJECT_ARRAY_INIT;
828 struct string_list deepen_not = STRING_LIST_INIT_DUP;
@@ -895,7 +900,7 @@ static void receive_needs(void)
900 if (!((allow_unadvertised_object_request & ALLOW_ANY_SHA1) == ALLOW_ANY_SHA1
901 || is_our_ref(o)))
902 has_non_tip = 1;
898 - add_object_array(o, NULL, &want_obj);
903 + add_object_array(o, NULL, want_obj);
904 }
905 }
906
@@ -907,7 +912,7 @@ static void receive_needs(void)
912 * by another process that handled the initial request.
913 */
914 if (has_non_tip)
910 - check_non_tip();
915 + check_non_tip(want_obj);
916
917 if (!use_sideband && daemon_mode)
918 no_progress = 1;
@@ -916,7 +921,7 @@ static void receive_needs(void)
921 return;
922
923 if (send_shallow_list(depth, deepen_rev_list, deepen_since,
919 - &deepen_not, &shallows))
924 + &deepen_not, &shallows, want_obj))
925 packet_flush(1);
926 object_array_clear(&shallows);
927 }
@@ -1042,6 +1047,7 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
1047 void upload_pack(struct upload_pack_options *options)
1048 {
1049 struct string_list symref = STRING_LIST_INIT_DUP;
1050 + struct object_array want_obj = OBJECT_ARRAY_INIT;
1051
1052 stateless_rpc = options->stateless_rpc;
1053 timeout = options->timeout;
@@ -1065,11 +1071,11 @@ void upload_pack(struct upload_pack_options *options)
1071 if (options->advertise_refs)
1072 return;
1073
1068 - receive_needs();
1074 + receive_needs(&want_obj);
1075 if (want_obj.nr) {
1076 struct object_array have_obj = OBJECT_ARRAY_INIT;
1071 - get_common_commits(&have_obj);
1072 - create_pack_file(&have_obj);
1077 + get_common_commits(&have_obj, &want_obj);
1078 + create_pack_file(&have_obj, &want_obj);
1079 }
1080 }
1081
@@ -1119,7 +1125,7 @@ static void upload_pack_data_clear(struct upload_pack_data *data)
1125 string_list_clear(&data->deepen_not, 0);
1126 }
1127
1122 -static int parse_want(const char *line)
1128 +static int parse_want(const char *line, struct object_array *want_obj)
1129 {
1130 const char *arg;
1131 if (skip_prefix(line, "want ", &arg)) {
@@ -1141,7 +1147,7 @@ static int parse_want(const char *line)
1147
1148 if (!(o->flags & WANTED)) {
1149 o->flags |= WANTED;
1144 - add_object_array(o, NULL, &want_obj);
1150 + add_object_array(o, NULL, want_obj);
1151 }
1152
1153 return 1;
@@ -1150,7 +1156,8 @@ static int parse_want(const char *line)
1156 return 0;
1157 }
1158
1153 -static int parse_want_ref(const char *line, struct string_list *wanted_refs)
1159 +static int parse_want_ref(const char *line, struct string_list *wanted_refs,
1160 + struct object_array *want_obj)
1161 {
1162 const char *arg;
1163 if (skip_prefix(line, "want-ref ", &arg)) {
@@ -1169,7 +1176,7 @@ static int parse_want_ref(const char *line, struct string_list *wanted_refs)
1176 o = parse_object_or_die(&oid, arg);
1177 if (!(o->flags & WANTED)) {
1178 o->flags |= WANTED;
1172 - add_object_array(o, NULL, &want_obj);
1179 + add_object_array(o, NULL, want_obj);
1180 }
1181
1182 return 1;
@@ -1194,16 +1201,18 @@ static int parse_have(const char *line, struct oid_array *haves)
1201 }
1202
1203 static void process_args(struct packet_reader *request,
1197 - struct upload_pack_data *data)
1204 + struct upload_pack_data *data,
1205 + struct object_array *want_obj)
1206 {
1207 while (packet_reader_read(request) != PACKET_READ_FLUSH) {
1208 const char *arg = request->line;
1209 const char *p;
1210
1211 /* process want */
1204 - if (parse_want(arg))
1212 + if (parse_want(arg, want_obj))
1213 continue;
1206 - if (allow_ref_in_want && parse_want_ref(arg, &data->wanted_refs))
1214 + if (allow_ref_in_want &&
1215 + parse_want_ref(arg, &data->wanted_refs, want_obj))
1216 continue;
1217 /* process have line */
1218 if (parse_have(arg, &data->haves))
@@ -1298,7 +1307,8 @@ static int process_haves(struct oid_array *haves, struct oid_array *common,
1307 }
1308
1309 static int send_acks(struct oid_array *acks, struct strbuf *response,
1301 - const struct object_array *have_obj)
1310 + const struct object_array *have_obj,
1311 + struct object_array *want_obj)
1312 {
1313 int i;
1314
@@ -1313,7 +1323,7 @@ static int send_acks(struct oid_array *acks, struct strbuf *response,
1323 oid_to_hex(&acks->oid[i]));
1324 }
1325
1316 - if (ok_to_give_up(have_obj)) {
1326 + if (ok_to_give_up(have_obj, want_obj)) {
1327 /* Send Ready */
1328 packet_buf_write(response, "ready\n");
1329 return 1;
@@ -1323,7 +1333,8 @@ static int send_acks(struct oid_array *acks, struct strbuf *response,
1333 }
1334
1335 static int process_haves_and_send_acks(struct upload_pack_data *data,
1326 - struct object_array *have_obj)
1336 + struct object_array *have_obj,
1337 + struct object_array *want_obj)
1338 {
1339 struct oid_array common = OID_ARRAY_INIT;
1340 struct strbuf response = STRBUF_INIT;
@@ -1332,7 +1343,7 @@ static int process_haves_and_send_acks(struct upload_pack_data *data,
1343 process_haves(&data->haves, &common, have_obj);
1344 if (data->done) {
1345 ret = 1;
1335 - } else if (send_acks(&common, &response, have_obj)) {
1346 + } else if (send_acks(&common, &response, have_obj, want_obj)) {
1347 packet_buf_delim(&response);
1348 ret = 1;
1349 } else {
@@ -1368,7 +1379,8 @@ static void send_wanted_ref_info(struct upload_pack_data *data)
1379 packet_delim(1);
1380 }
1381
1371 -static void send_shallow_info(struct upload_pack_data *data)
1382 +static void send_shallow_info(struct upload_pack_data *data,
1383 + struct object_array *want_obj)
1384 {
1385 /* No shallow info needs to be sent */
1386 if (!data->depth && !data->deepen_rev_list && !data->shallows.nr &&
@@ -1379,9 +1391,10 @@ static void send_shallow_info(struct upload_pack_data *data)
1391
1392 if (!send_shallow_list(data->depth, data->deepen_rev_list,
1393 data->deepen_since, &data->deepen_not,
1382 - &data->shallows) &&
1394 + &data->shallows, want_obj) &&
1395 is_repository_shallow(the_repository))
1384 - deepen(INFINITE_DEPTH, data->deepen_relative, &data->shallows);
1396 + deepen(INFINITE_DEPTH, data->deepen_relative, &data->shallows,
1397 + want_obj);
1398
1399 packet_delim(1);
1400 }
@@ -1400,6 +1413,8 @@ int upload_pack_v2(struct repository *r, struct argv_array *keys,
1413 struct upload_pack_data data;
1414 /* NEEDSWORK: make this non-static */
1415 static struct object_array have_obj;
1416 + /* NEEDSWORK: make this non-static */
1417 + static struct object_array want_obj;
1418
1419 git_config(upload_pack_config, NULL);
1420
@@ -1409,7 +1424,7 @@ int upload_pack_v2(struct repository *r, struct argv_array *keys,
1424 while (state != FETCH_DONE) {
1425 switch (state) {
1426 case FETCH_PROCESS_ARGS:
1412 - process_args(request, &data);
1427 + process_args(request, &data, &want_obj);
1428
1429 if (!want_obj.nr) {
1430 /*
@@ -1431,17 +1446,18 @@ int upload_pack_v2(struct repository *r, struct argv_array *keys,
1446 }
1447 break;
1448 case FETCH_SEND_ACKS:
1434 - if (process_haves_and_send_acks(&data, &have_obj))
1449 + if (process_haves_and_send_acks(&data, &have_obj,
1450 + &want_obj))
1451 state = FETCH_SEND_PACK;
1452 else
1453 state = FETCH_DONE;
1454 break;
1455 case FETCH_SEND_PACK:
1456 send_wanted_ref_info(&data);
1441 - send_shallow_info(&data);
1457 + send_shallow_info(&data, &want_obj);
1458
1459 packet_write_fmt(1, "packfile\n");
1444 - create_pack_file(&have_obj);
1460 + create_pack_file(&have_obj, &want_obj);
1461 state = FETCH_DONE;
1462 break;
1463 case FETCH_DONE: