fetch-pack: with packfile URIs, use index-pack arg

Unify the index-pack arguments used when processing the inline pack and when downloading packfiles referenced by URIs. This is done by teaching get_pack() to also store the index-pack arguments whenever at least one packfile URI is given, and then when processing the packfile URI(s), using the stored arguments. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Feb 22, 2021 at 11:20 UTC b664e9ffa153189dae9b88f32d1c5fedcf85056a
1 file changed +23 -11
fetch-pack.c
+23 -11
@@ -797,12 +797,13 @@ static void write_promisor_file(const char *keep_name,
797 }
798
799 /*
800 - * Pass 1 as "only_packfile" if the pack received is the only pack in this
801 - * fetch request (that is, if there were no packfile URIs provided).
800 + * If packfile URIs were provided, pass a non-NULL pointer to index_pack_args.
801 + * The strings to pass as the --index-pack-arg arguments to http-fetch will be
802 + * stored there. (It must be freed by the caller.)
803 */
804 static int get_pack(struct fetch_pack_args *args,
805 int xd[2], struct string_list *pack_lockfiles,
805 - int only_packfile,
806 + struct strvec *index_pack_args,
807 struct ref **sought, int nr_sought)
808 {
809 struct async demux;
@@ -845,7 +846,7 @@ static int get_pack(struct fetch_pack_args *args,
846 strvec_push(&cmd.args, alternate_shallow_file);
847 }
848
848 - if (do_keep || args->from_promisor) {
849 + if (do_keep || args->from_promisor || index_pack_args) {
850 if (pack_lockfiles)
851 cmd.out = -1;
852 cmd_name = "index-pack";
@@ -863,7 +864,7 @@ static int get_pack(struct fetch_pack_args *args,
864 "--keep=fetch-pack %"PRIuMAX " on %s",
865 (uintmax_t)getpid(), hostname);
866 }
866 - if (only_packfile && args->check_self_contained_and_connected)
867 + if (!index_pack_args && args->check_self_contained_and_connected)
868 strvec_push(&cmd.args, "--check-self-contained-and-connected");
869 else
870 /*
@@ -901,7 +902,7 @@ static int get_pack(struct fetch_pack_args *args,
902 : transfer_fsck_objects >= 0
903 ? transfer_fsck_objects
904 : 0) {
904 - if (args->from_promisor || !only_packfile)
905 + if (args->from_promisor || index_pack_args)
906 /*
907 * We cannot use --strict in index-pack because it
908 * checks both broken objects and links, but we only
@@ -913,6 +914,13 @@ static int get_pack(struct fetch_pack_args *args,
914 fsck_msg_types.buf);
915 }
916
917 + if (index_pack_args) {
918 + int i;
919 +
920 + for (i = 0; i < cmd.args.nr; i++)
921 + strvec_push(index_pack_args, cmd.args.v[i]);
922 + }
923 +
924 cmd.in = demux.out;
925 cmd.git_cmd = 1;
926 if (start_command(&cmd))
@@ -1084,7 +1092,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
1092 alternate_shallow_file = setup_temporary_shallow(si->shallow);
1093 else
1094 alternate_shallow_file = NULL;
1087 - if (get_pack(args, fd, pack_lockfiles, 1, sought, nr_sought))
1095 + if (get_pack(args, fd, pack_lockfiles, NULL, sought, nr_sought))
1096 die(_("git fetch-pack: fetch failed."));
1097
1098 all_done:
@@ -1535,6 +1543,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1543 int seen_ack = 0;
1544 struct string_list packfile_uris = STRING_LIST_INIT_DUP;
1545 int i;
1546 + struct strvec index_pack_args = STRVEC_INIT;
1547
1548 negotiator = &negotiator_alloc;
1549 fetch_negotiator_init(r, negotiator);
@@ -1624,7 +1633,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1633 receive_packfile_uris(&reader, &packfile_uris);
1634 process_section_header(&reader, "packfile", 0);
1635 if (get_pack(args, fd, pack_lockfiles,
1627 - !packfile_uris.nr, sought, nr_sought))
1636 + packfile_uris.nr ? &index_pack_args : NULL,
1637 + sought, nr_sought))
1638 die(_("git fetch-pack: fetch failed."));
1639 do_check_stateless_delimiter(args, &reader);
1640
@@ -1636,6 +1646,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1646 }
1647
1648 for (i = 0; i < packfile_uris.nr; i++) {
1649 + int j;
1650 struct child_process cmd = CHILD_PROCESS_INIT;
1651 char packname[GIT_MAX_HEXSZ + 1];
1652 const char *uri = packfile_uris.items[i].string +
@@ -1645,9 +1656,9 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1656 strvec_pushf(&cmd.args, "--packfile=%.*s",
1657 (int) the_hash_algo->hexsz,
1658 packfile_uris.items[i].string);
1648 - strvec_push(&cmd.args, "--index-pack-arg=index-pack");
1649 - strvec_push(&cmd.args, "--index-pack-arg=--stdin");
1650 - strvec_push(&cmd.args, "--index-pack-arg=--keep");
1659 + for (j = 0; j < index_pack_args.nr; j++)
1660 + strvec_pushf(&cmd.args, "--index-pack-arg=%s",
1661 + index_pack_args.v[j]);
1662 strvec_push(&cmd.args, uri);
1663 cmd.git_cmd = 1;
1664 cmd.no_stdin = 1;
@@ -1683,6 +1694,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1694 packname));
1695 }
1696 string_list_clear(&packfile_uris, 0);
1697 + strvec_clear(&index_pack_args);
1698
1699 if (negotiator)
1700 negotiator->release(negotiator);