@@ -790,21 +790,44 @@ static void create_promisor_file(const char *keep_name,
790
790
strbuf_release (& promisor_name );
791
791
}
792
792
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
+
793
813
/*
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.)
796
817
*/
797
818
static int get_pack (struct fetch_pack_args * args ,
798
819
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 )
801
823
{
802
824
struct async demux ;
803
825
int do_keep = args -> keep_pack ;
804
826
const char * cmd_name ;
805
827
struct pack_header header ;
806
828
int pass_header = 0 ;
807
829
struct child_process cmd = CHILD_PROCESS_INIT ;
830
+ int fsck_objects = 0 ;
808
831
int ret ;
809
832
810
833
memset (& demux , 0 , sizeof (demux ));
@@ -839,8 +862,15 @@ static int get_pack(struct fetch_pack_args *args,
839
862
strvec_push (& cmd .args , alternate_shallow_file );
840
863
}
841
864
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 )
844
874
cmd .out = -1 ;
845
875
cmd_name = "index-pack" ;
846
876
strvec_push (& cmd .args , cmd_name );
@@ -857,7 +887,7 @@ static int get_pack(struct fetch_pack_args *args,
857
887
"--keep=fetch-pack %" PRIuMAX " on %s" ,
858
888
(uintmax_t )getpid (), hostname );
859
889
}
860
- if (only_packfile && args -> check_self_contained_and_connected )
890
+ if (! index_pack_args && args -> check_self_contained_and_connected )
861
891
strvec_push (& cmd .args , "--check-self-contained-and-connected" );
862
892
else
863
893
/*
@@ -890,12 +920,8 @@ static int get_pack(struct fetch_pack_args *args,
890
920
strvec_pushf (& cmd .args , "--pack_header=%" PRIu32 ",%" PRIu32 ,
891
921
ntohl (header .hdr_version ),
892
922
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 )
899
925
/*
900
926
* We cannot use --strict in index-pack because it
901
927
* checks both broken objects and links, but we only
@@ -907,14 +933,26 @@ static int get_pack(struct fetch_pack_args *args,
907
933
fsck_msg_types .buf );
908
934
}
909
935
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
+
910
943
cmd .in = demux .out ;
911
944
cmd .git_cmd = 1 ;
912
945
if (start_command (& cmd ))
913
946
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" ));
916
953
if (pack_lockfile )
917
954
string_list_append_nodup (pack_lockfiles , pack_lockfile );
955
+ parse_gitmodules_oids (cmd .out , gitmodules_oids );
918
956
close (cmd .out );
919
957
}
920
958
@@ -949,6 +987,22 @@ static int cmp_ref_by_name(const void *a_, const void *b_)
949
987
return strcmp (a -> name , b -> name );
950
988
}
951
989
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
+
952
1006
static struct ref * do_fetch_pack (struct fetch_pack_args * args ,
953
1007
int fd [2 ],
954
1008
const struct ref * orig_ref ,
@@ -963,6 +1017,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
963
1017
int agent_len ;
964
1018
struct fetch_negotiator negotiator_alloc ;
965
1019
struct fetch_negotiator * negotiator ;
1020
+ struct oidset gitmodules_oids = OIDSET_INIT ;
966
1021
967
1022
negotiator = & negotiator_alloc ;
968
1023
fetch_negotiator_init (r , negotiator );
@@ -1078,8 +1133,10 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
1078
1133
alternate_shallow_file = setup_temporary_shallow (si -> shallow );
1079
1134
else
1080
1135
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 ))
1082
1138
die (_ ("git fetch-pack: fetch failed." ));
1139
+ fsck_gitmodules_oids (& gitmodules_oids );
1083
1140
1084
1141
all_done :
1085
1142
if (negotiator )
@@ -1529,6 +1586,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1529
1586
int seen_ack = 0 ;
1530
1587
struct string_list packfile_uris = STRING_LIST_INIT_DUP ;
1531
1588
int i ;
1589
+ struct strvec index_pack_args = STRVEC_INIT ;
1590
+ struct oidset gitmodules_oids = OIDSET_INIT ;
1532
1591
1533
1592
negotiator = & negotiator_alloc ;
1534
1593
fetch_negotiator_init (r , negotiator );
@@ -1618,7 +1677,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1618
1677
receive_packfile_uris (& reader , & packfile_uris );
1619
1678
process_section_header (& reader , "packfile" , 0 );
1620
1679
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 ))
1622
1682
die (_ ("git fetch-pack: fetch failed." ));
1623
1683
do_check_stateless_delimiter (args , & reader );
1624
1684
@@ -1630,6 +1690,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1630
1690
}
1631
1691
1632
1692
for (i = 0 ; i < packfile_uris .nr ; i ++ ) {
1693
+ int j ;
1633
1694
struct child_process cmd = CHILD_PROCESS_INIT ;
1634
1695
char packname [GIT_MAX_HEXSZ + 1 ];
1635
1696
const char * uri = packfile_uris .items [i ].string +
@@ -1639,6 +1700,9 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1639
1700
strvec_pushf (& cmd .args , "--packfile=%.*s" ,
1640
1701
(int ) the_hash_algo -> hexsz ,
1641
1702
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 ]);
1642
1706
strvec_push (& cmd .args , uri );
1643
1707
cmd .git_cmd = 1 ;
1644
1708
cmd .no_stdin = 1 ;
@@ -1657,6 +1721,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1657
1721
1658
1722
packname [the_hash_algo -> hexsz ] = '\0' ;
1659
1723
1724
+ parse_gitmodules_oids (cmd .out , & gitmodules_oids );
1725
+
1660
1726
close (cmd .out );
1661
1727
1662
1728
if (finish_command (& cmd ))
@@ -1674,6 +1740,9 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1674
1740
packname ));
1675
1741
}
1676
1742
string_list_clear (& packfile_uris , 0 );
1743
+ strvec_clear (& index_pack_args );
1744
+
1745
+ fsck_gitmodules_oids (& gitmodules_oids );
1677
1746
1678
1747
if (negotiator )
1679
1748
negotiator -> release (negotiator );
0 commit comments