@@ -796,6 +796,26 @@ static void write_promisor_file(const char *keep_name,
796796 strbuf_release (& promisor_name );
797797}
798798
799+ static void parse_gitmodules_oids (int fd , struct oidset * gitmodules_oids )
800+ {
801+ int len = the_hash_algo -> hexsz + 1 ; /* hash + NL */
802+
803+ do {
804+ char hex_hash [GIT_MAX_HEXSZ + 1 ];
805+ int read_len = read_in_full (fd , hex_hash , len );
806+ struct object_id oid ;
807+ const char * end ;
808+
809+ if (!read_len )
810+ return ;
811+ if (read_len != len )
812+ die ("invalid length read %d" , read_len );
813+ if (parse_oid_hex (hex_hash , & oid , & end ) || * end != '\n' )
814+ die ("invalid hash" );
815+ oidset_insert (gitmodules_oids , & oid );
816+ } while (1 );
817+ }
818+
799819/*
800820 * If packfile URIs were provided, pass a non-NULL pointer to index_pack_args.
801821 * The strings to pass as the --index-pack-arg arguments to http-fetch will be
@@ -804,14 +824,16 @@ static void write_promisor_file(const char *keep_name,
804824static int get_pack (struct fetch_pack_args * args ,
805825 int xd [2 ], struct string_list * pack_lockfiles ,
806826 struct strvec * index_pack_args ,
807- struct ref * * sought , int nr_sought )
827+ struct ref * * sought , int nr_sought ,
828+ struct oidset * gitmodules_oids )
808829{
809830 struct async demux ;
810831 int do_keep = args -> keep_pack ;
811832 const char * cmd_name ;
812833 struct pack_header header ;
813834 int pass_header = 0 ;
814835 struct child_process cmd = CHILD_PROCESS_INIT ;
836+ int fsck_objects = 0 ;
815837 int ret ;
816838
817839 memset (& demux , 0 , sizeof (demux ));
@@ -846,8 +868,15 @@ static int get_pack(struct fetch_pack_args *args,
846868 strvec_push (& cmd .args , alternate_shallow_file );
847869 }
848870
849- if (do_keep || args -> from_promisor || index_pack_args ) {
850- if (pack_lockfiles )
871+ if (fetch_fsck_objects >= 0
872+ ? fetch_fsck_objects
873+ : transfer_fsck_objects >= 0
874+ ? transfer_fsck_objects
875+ : 0 )
876+ fsck_objects = 1 ;
877+
878+ if (do_keep || args -> from_promisor || index_pack_args || fsck_objects ) {
879+ if (pack_lockfiles || fsck_objects )
851880 cmd .out = -1 ;
852881 cmd_name = "index-pack" ;
853882 strvec_push (& cmd .args , cmd_name );
@@ -897,11 +926,7 @@ static int get_pack(struct fetch_pack_args *args,
897926 strvec_pushf (& cmd .args , "--pack_header=%" PRIu32 ",%" PRIu32 ,
898927 ntohl (header .hdr_version ),
899928 ntohl (header .hdr_entries ));
900- if (fetch_fsck_objects >= 0
901- ? fetch_fsck_objects
902- : transfer_fsck_objects >= 0
903- ? transfer_fsck_objects
904- : 0 ) {
929+ if (fsck_objects ) {
905930 if (args -> from_promisor || index_pack_args )
906931 /*
907932 * We cannot use --strict in index-pack because it
@@ -925,10 +950,15 @@ static int get_pack(struct fetch_pack_args *args,
925950 cmd .git_cmd = 1 ;
926951 if (start_command (& cmd ))
927952 die (_ ("fetch-pack: unable to fork off %s" ), cmd_name );
928- if (do_keep && pack_lockfiles ) {
929- char * pack_lockfile = index_pack_lockfile (cmd .out );
953+ if (do_keep && (pack_lockfiles || fsck_objects )) {
954+ int is_well_formed ;
955+ char * pack_lockfile = index_pack_lockfile (cmd .out , & is_well_formed );
956+
957+ if (!is_well_formed )
958+ die (_ ("fetch-pack: invalid index-pack output" ));
930959 if (pack_lockfile )
931960 string_list_append_nodup (pack_lockfiles , pack_lockfile );
961+ parse_gitmodules_oids (cmd .out , gitmodules_oids );
932962 close (cmd .out );
933963 }
934964
@@ -963,6 +993,22 @@ static int cmp_ref_by_name(const void *a_, const void *b_)
963993 return strcmp (a -> name , b -> name );
964994}
965995
996+ static void fsck_gitmodules_oids (struct oidset * gitmodules_oids )
997+ {
998+ struct oidset_iter iter ;
999+ const struct object_id * oid ;
1000+ struct fsck_options fo = FSCK_OPTIONS_STRICT ;
1001+
1002+ if (!oidset_size (gitmodules_oids ))
1003+ return ;
1004+
1005+ oidset_iter_init (gitmodules_oids , & iter );
1006+ while ((oid = oidset_iter_next (& iter )))
1007+ register_found_gitmodules (oid );
1008+ if (fsck_finish (& fo ))
1009+ die ("fsck failed" );
1010+ }
1011+
9661012static struct ref * do_fetch_pack (struct fetch_pack_args * args ,
9671013 int fd [2 ],
9681014 const struct ref * orig_ref ,
@@ -977,6 +1023,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
9771023 int agent_len ;
9781024 struct fetch_negotiator negotiator_alloc ;
9791025 struct fetch_negotiator * negotiator ;
1026+ struct oidset gitmodules_oids = OIDSET_INIT ;
9801027
9811028 negotiator = & negotiator_alloc ;
9821029 fetch_negotiator_init (r , negotiator );
@@ -1092,8 +1139,10 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
10921139 alternate_shallow_file = setup_temporary_shallow (si -> shallow );
10931140 else
10941141 alternate_shallow_file = NULL ;
1095- if (get_pack (args , fd , pack_lockfiles , NULL , sought , nr_sought ))
1142+ if (get_pack (args , fd , pack_lockfiles , NULL , sought , nr_sought ,
1143+ & gitmodules_oids ))
10961144 die (_ ("git fetch-pack: fetch failed." ));
1145+ fsck_gitmodules_oids (& gitmodules_oids );
10971146
10981147 all_done :
10991148 if (negotiator )
@@ -1544,6 +1593,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
15441593 struct string_list packfile_uris = STRING_LIST_INIT_DUP ;
15451594 int i ;
15461595 struct strvec index_pack_args = STRVEC_INIT ;
1596+ struct oidset gitmodules_oids = OIDSET_INIT ;
15471597
15481598 negotiator = & negotiator_alloc ;
15491599 fetch_negotiator_init (r , negotiator );
@@ -1634,7 +1684,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
16341684 process_section_header (& reader , "packfile" , 0 );
16351685 if (get_pack (args , fd , pack_lockfiles ,
16361686 packfile_uris .nr ? & index_pack_args : NULL ,
1637- sought , nr_sought ))
1687+ sought , nr_sought , & gitmodules_oids ))
16381688 die (_ ("git fetch-pack: fetch failed." ));
16391689 do_check_stateless_delimiter (args , & reader );
16401690
@@ -1677,6 +1727,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
16771727
16781728 packname [the_hash_algo -> hexsz ] = '\0' ;
16791729
1730+ parse_gitmodules_oids (cmd .out , & gitmodules_oids );
1731+
16801732 close (cmd .out );
16811733
16821734 if (finish_command (& cmd ))
@@ -1696,6 +1748,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
16961748 string_list_clear (& packfile_uris , 0 );
16971749 strvec_clear (& index_pack_args );
16981750
1751+ fsck_gitmodules_oids (& gitmodules_oids );
1752+
16991753 if (negotiator )
17001754 negotiator -> release (negotiator );
17011755
0 commit comments