@@ -790,21 +790,44 @@ static void create_promisor_file(const char *keep_name,
790790 strbuf_release (& promisor_name );
791791}
792792
793+ static void parse_gitmodules_oids (int fd , struct oidset * gitmodules_oids )
794+ {
795+ int len = the_hash_algo -> hexsz + 1 ; /* hash + NL */
796+
797+ do {
798+ char hex_hash [GIT_MAX_HEXSZ + 1 ];
799+ int read_len = read_in_full (fd , hex_hash , len );
800+ struct object_id oid ;
801+ const char * end ;
802+
803+ if (!read_len )
804+ return ;
805+ if (read_len != len )
806+ die ("invalid length read %d" , read_len );
807+ if (parse_oid_hex (hex_hash , & oid , & end ) || * end != '\n' )
808+ die ("invalid hash" );
809+ oidset_insert (gitmodules_oids , & oid );
810+ } while (1 );
811+ }
812+
793813/*
794- * Pass 1 as "only_packfile" if the pack received is the only pack in this
795- * fetch request (that is, if there were no packfile URIs provided).
814+ * If packfile URIs were provided, pass a non-NULL pointer to index_pack_args.
815+ * The strings to pass as the --index-pack-arg arguments to http-fetch will be
816+ * stored there. (It must be freed by the caller.)
796817 */
797818static int get_pack (struct fetch_pack_args * args ,
798819 int xd [2 ], struct string_list * pack_lockfiles ,
799- int only_packfile ,
800- struct ref * * sought , int nr_sought )
820+ struct strvec * index_pack_args ,
821+ struct ref * * sought , int nr_sought ,
822+ struct oidset * gitmodules_oids )
801823{
802824 struct async demux ;
803825 int do_keep = args -> keep_pack ;
804826 const char * cmd_name ;
805827 struct pack_header header ;
806828 int pass_header = 0 ;
807829 struct child_process cmd = CHILD_PROCESS_INIT ;
830+ int fsck_objects = 0 ;
808831 int ret ;
809832
810833 memset (& demux , 0 , sizeof (demux ));
@@ -839,8 +862,15 @@ static int get_pack(struct fetch_pack_args *args,
839862 strvec_push (& cmd .args , alternate_shallow_file );
840863 }
841864
842- if (do_keep || args -> from_promisor ) {
843- if (pack_lockfiles )
865+ if (fetch_fsck_objects >= 0
866+ ? fetch_fsck_objects
867+ : transfer_fsck_objects >= 0
868+ ? transfer_fsck_objects
869+ : 0 )
870+ fsck_objects = 1 ;
871+
872+ if (do_keep || args -> from_promisor || index_pack_args || fsck_objects ) {
873+ if (pack_lockfiles || fsck_objects )
844874 cmd .out = -1 ;
845875 cmd_name = "index-pack" ;
846876 strvec_push (& cmd .args , cmd_name );
@@ -857,7 +887,7 @@ static int get_pack(struct fetch_pack_args *args,
857887 "--keep=fetch-pack %" PRIuMAX " on %s" ,
858888 (uintmax_t )getpid (), hostname );
859889 }
860- if (only_packfile && args -> check_self_contained_and_connected )
890+ if (! index_pack_args && args -> check_self_contained_and_connected )
861891 strvec_push (& cmd .args , "--check-self-contained-and-connected" );
862892 else
863893 /*
@@ -890,12 +920,8 @@ static int get_pack(struct fetch_pack_args *args,
890920 strvec_pushf (& cmd .args , "--pack_header=%" PRIu32 ",%" PRIu32 ,
891921 ntohl (header .hdr_version ),
892922 ntohl (header .hdr_entries ));
893- if (fetch_fsck_objects >= 0
894- ? fetch_fsck_objects
895- : transfer_fsck_objects >= 0
896- ? transfer_fsck_objects
897- : 0 ) {
898- if (args -> from_promisor || !only_packfile )
923+ if (fsck_objects ) {
924+ if (args -> from_promisor || index_pack_args )
899925 /*
900926 * We cannot use --strict in index-pack because it
901927 * checks both broken objects and links, but we only
@@ -907,14 +933,26 @@ static int get_pack(struct fetch_pack_args *args,
907933 fsck_msg_types .buf );
908934 }
909935
936+ if (index_pack_args ) {
937+ int i ;
938+
939+ for (i = 0 ; i < cmd .args .nr ; i ++ )
940+ strvec_push (index_pack_args , cmd .args .v [i ]);
941+ }
942+
910943 cmd .in = demux .out ;
911944 cmd .git_cmd = 1 ;
912945 if (start_command (& cmd ))
913946 die (_ ("fetch-pack: unable to fork off %s" ), cmd_name );
914- if (do_keep && pack_lockfiles ) {
915- char * pack_lockfile = index_pack_lockfile (cmd .out );
947+ if (do_keep && (pack_lockfiles || fsck_objects )) {
948+ int is_well_formed ;
949+ char * pack_lockfile = index_pack_lockfile (cmd .out , & is_well_formed );
950+
951+ if (!is_well_formed )
952+ die (_ ("fetch-pack: invalid index-pack output" ));
916953 if (pack_lockfile )
917954 string_list_append_nodup (pack_lockfiles , pack_lockfile );
955+ parse_gitmodules_oids (cmd .out , gitmodules_oids );
918956 close (cmd .out );
919957 }
920958
@@ -949,6 +987,22 @@ static int cmp_ref_by_name(const void *a_, const void *b_)
949987 return strcmp (a -> name , b -> name );
950988}
951989
990+ static void fsck_gitmodules_oids (struct oidset * gitmodules_oids )
991+ {
992+ struct oidset_iter iter ;
993+ const struct object_id * oid ;
994+ struct fsck_options fo = FSCK_OPTIONS_STRICT ;
995+
996+ if (!oidset_size (gitmodules_oids ))
997+ return ;
998+
999+ oidset_iter_init (gitmodules_oids , & iter );
1000+ while ((oid = oidset_iter_next (& iter )))
1001+ register_found_gitmodules (oid );
1002+ if (fsck_finish (& fo ))
1003+ die ("fsck failed" );
1004+ }
1005+
9521006static struct ref * do_fetch_pack (struct fetch_pack_args * args ,
9531007 int fd [2 ],
9541008 const struct ref * orig_ref ,
@@ -963,6 +1017,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
9631017 int agent_len ;
9641018 struct fetch_negotiator negotiator_alloc ;
9651019 struct fetch_negotiator * negotiator ;
1020+ struct oidset gitmodules_oids = OIDSET_INIT ;
9661021
9671022 negotiator = & negotiator_alloc ;
9681023 fetch_negotiator_init (r , negotiator );
@@ -1078,8 +1133,10 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
10781133 alternate_shallow_file = setup_temporary_shallow (si -> shallow );
10791134 else
10801135 alternate_shallow_file = NULL ;
1081- if (get_pack (args , fd , pack_lockfiles , 1 , sought , nr_sought ))
1136+ if (get_pack (args , fd , pack_lockfiles , NULL , sought , nr_sought ,
1137+ & gitmodules_oids ))
10821138 die (_ ("git fetch-pack: fetch failed." ));
1139+ fsck_gitmodules_oids (& gitmodules_oids );
10831140
10841141 all_done :
10851142 if (negotiator )
@@ -1529,6 +1586,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
15291586 int seen_ack = 0 ;
15301587 struct string_list packfile_uris = STRING_LIST_INIT_DUP ;
15311588 int i ;
1589+ struct strvec index_pack_args = STRVEC_INIT ;
1590+ struct oidset gitmodules_oids = OIDSET_INIT ;
15321591
15331592 negotiator = & negotiator_alloc ;
15341593 fetch_negotiator_init (r , negotiator );
@@ -1618,7 +1677,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
16181677 receive_packfile_uris (& reader , & packfile_uris );
16191678 process_section_header (& reader , "packfile" , 0 );
16201679 if (get_pack (args , fd , pack_lockfiles ,
1621- !packfile_uris .nr , sought , nr_sought ))
1680+ packfile_uris .nr ? & index_pack_args : NULL ,
1681+ sought , nr_sought , & gitmodules_oids ))
16221682 die (_ ("git fetch-pack: fetch failed." ));
16231683 do_check_stateless_delimiter (args , & reader );
16241684
@@ -1630,6 +1690,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
16301690 }
16311691
16321692 for (i = 0 ; i < packfile_uris .nr ; i ++ ) {
1693+ int j ;
16331694 struct child_process cmd = CHILD_PROCESS_INIT ;
16341695 char packname [GIT_MAX_HEXSZ + 1 ];
16351696 const char * uri = packfile_uris .items [i ].string +
@@ -1639,6 +1700,9 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
16391700 strvec_pushf (& cmd .args , "--packfile=%.*s" ,
16401701 (int ) the_hash_algo -> hexsz ,
16411702 packfile_uris .items [i ].string );
1703+ for (j = 0 ; j < index_pack_args .nr ; j ++ )
1704+ strvec_pushf (& cmd .args , "--index-pack-arg=%s" ,
1705+ index_pack_args .v [j ]);
16421706 strvec_push (& cmd .args , uri );
16431707 cmd .git_cmd = 1 ;
16441708 cmd .no_stdin = 1 ;
@@ -1657,6 +1721,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
16571721
16581722 packname [the_hash_algo -> hexsz ] = '\0' ;
16591723
1724+ parse_gitmodules_oids (cmd .out , & gitmodules_oids );
1725+
16601726 close (cmd .out );
16611727
16621728 if (finish_command (& cmd ))
@@ -1674,6 +1740,9 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
16741740 packname ));
16751741 }
16761742 string_list_clear (& packfile_uris , 0 );
1743+ strvec_clear (& index_pack_args );
1744+
1745+ fsck_gitmodules_oids (& gitmodules_oids );
16771746
16781747 if (negotiator )
16791748 negotiator -> release (negotiator );
0 commit comments