@@ -44,6 +44,7 @@ static int fix_thin = 1;
44
44
static const char * head_name ;
45
45
static void * head_name_to_free ;
46
46
static int sent_capabilities ;
47
+ static const char * alt_shallow_file ;
47
48
48
49
static enum deny_action parse_deny_action (const char * var , const char * value )
49
50
{
@@ -190,6 +191,7 @@ struct command {
190
191
const char * error_string ;
191
192
unsigned int skip_update :1 ,
192
193
did_not_exist :1 ;
194
+ int index ;
193
195
unsigned char old_sha1 [20 ];
194
196
unsigned char new_sha1 [20 ];
195
197
char ref_name [FLEX_ARRAY ]; /* more */
@@ -688,7 +690,7 @@ static int iterate_receive_command_list(void *cb_data, unsigned char sha1[20])
688
690
struct command * cmd = * cmd_list ;
689
691
690
692
while (cmd ) {
691
- if (!is_null_sha1 (cmd -> new_sha1 )) {
693
+ if (!is_null_sha1 (cmd -> new_sha1 ) && ! cmd -> skip_update ) {
692
694
hashcpy (sha1 , cmd -> new_sha1 );
693
695
* cmd_list = cmd -> next ;
694
696
return 0 ;
@@ -755,7 +757,7 @@ static void execute_commands(struct command *commands, const char *unpacker_erro
755
757
}
756
758
}
757
759
758
- static struct command * read_head_info (void )
760
+ static struct command * read_head_info (struct sha1_array * shallow )
759
761
{
760
762
struct command * commands = NULL ;
761
763
struct command * * p = & commands ;
@@ -769,6 +771,14 @@ static struct command *read_head_info(void)
769
771
line = packet_read_line (0 , & len );
770
772
if (!line )
771
773
break ;
774
+
775
+ if (len == 48 && !prefixcmp (line , "shallow " )) {
776
+ if (get_sha1_hex (line + 8 , old_sha1 ))
777
+ die ("protocol error: expected shallow sha, got '%s'" , line + 8 );
778
+ sha1_array_append (shallow , old_sha1 );
779
+ continue ;
780
+ }
781
+
772
782
if (len < 83 ||
773
783
line [40 ] != ' ' ||
774
784
line [81 ] != ' ' ||
@@ -820,7 +830,7 @@ static const char *parse_pack_header(struct pack_header *hdr)
820
830
821
831
static const char * pack_lockfile ;
822
832
823
- static const char * unpack (int err_fd )
833
+ static const char * unpack (int err_fd , struct shallow_info * si )
824
834
{
825
835
struct pack_header hdr ;
826
836
struct argv_array av = ARGV_ARRAY_INIT ;
@@ -844,6 +854,11 @@ static const char *unpack(int err_fd)
844
854
"--pack_header=%" PRIu32 ",%" PRIu32 ,
845
855
ntohl (hdr .hdr_version ), ntohl (hdr .hdr_entries ));
846
856
857
+ if (si -> nr_ours || si -> nr_theirs ) {
858
+ alt_shallow_file = setup_temporary_shallow (si -> shallow );
859
+ argv_array_pushl (& av , "--shallow-file" , alt_shallow_file , NULL );
860
+ }
861
+
847
862
memset (& child , 0 , sizeof (child ));
848
863
if (ntohl (hdr .hdr_entries ) < unpack_limit ) {
849
864
argv_array_pushl (& av , "unpack-objects" , hdr_arg , NULL );
@@ -889,26 +904,62 @@ static const char *unpack(int err_fd)
889
904
return NULL ;
890
905
}
891
906
892
- static const char * unpack_with_sideband (void )
907
+ static const char * unpack_with_sideband (struct shallow_info * si )
893
908
{
894
909
struct async muxer ;
895
910
const char * ret ;
896
911
897
912
if (!use_sideband )
898
- return unpack (0 );
913
+ return unpack (0 , si );
899
914
900
915
memset (& muxer , 0 , sizeof (muxer ));
901
916
muxer .proc = copy_to_sideband ;
902
917
muxer .in = -1 ;
903
918
if (start_async (& muxer ))
904
919
return NULL ;
905
920
906
- ret = unpack (muxer .in );
921
+ ret = unpack (muxer .in , si );
907
922
908
923
finish_async (& muxer );
909
924
return ret ;
910
925
}
911
926
927
+ static void update_shallow_info (struct command * commands ,
928
+ struct shallow_info * si ,
929
+ struct sha1_array * ref )
930
+ {
931
+ struct command * cmd ;
932
+ int * ref_status ;
933
+ remove_nonexistent_theirs_shallow (si );
934
+ /* XXX remove_nonexistent_ours_in_pack() */
935
+ if (!si -> nr_ours && !si -> nr_theirs )
936
+ return ;
937
+
938
+ for (cmd = commands ; cmd ; cmd = cmd -> next ) {
939
+ if (is_null_sha1 (cmd -> new_sha1 ))
940
+ continue ;
941
+ sha1_array_append (ref , cmd -> new_sha1 );
942
+ cmd -> index = ref -> nr - 1 ;
943
+ }
944
+ si -> ref = ref ;
945
+
946
+ ref_status = xmalloc (sizeof (* ref_status ) * ref -> nr );
947
+ assign_shallow_commits_to_refs (si , NULL , ref_status );
948
+ for (cmd = commands ; cmd ; cmd = cmd -> next ) {
949
+ if (is_null_sha1 (cmd -> new_sha1 ))
950
+ continue ;
951
+ if (ref_status [cmd -> index ]) {
952
+ cmd -> error_string = "shallow update not allowed" ;
953
+ cmd -> skip_update = 1 ;
954
+ }
955
+ }
956
+ if (alt_shallow_file && * alt_shallow_file ) {
957
+ unlink (alt_shallow_file );
958
+ alt_shallow_file = NULL ;
959
+ }
960
+ free (ref_status );
961
+ }
962
+
912
963
static void report (struct command * commands , const char * unpack_status )
913
964
{
914
965
struct command * cmd ;
@@ -950,6 +1001,9 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
950
1001
int i ;
951
1002
char * dir = NULL ;
952
1003
struct command * commands ;
1004
+ struct sha1_array shallow = SHA1_ARRAY_INIT ;
1005
+ struct sha1_array ref = SHA1_ARRAY_INIT ;
1006
+ struct shallow_info si ;
953
1007
954
1008
packet_trace_identity ("receive-pack" );
955
1009
@@ -1006,11 +1060,14 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
1006
1060
if (advertise_refs )
1007
1061
return 0 ;
1008
1062
1009
- if ((commands = read_head_info ()) != NULL ) {
1063
+ if ((commands = read_head_info (& shallow )) != NULL ) {
1010
1064
const char * unpack_status = NULL ;
1011
1065
1012
- if (!delete_only (commands ))
1013
- unpack_status = unpack_with_sideband ();
1066
+ prepare_shallow_info (& si , & shallow );
1067
+ if (!delete_only (commands )) {
1068
+ unpack_status = unpack_with_sideband (& si );
1069
+ update_shallow_info (commands , & si , & ref );
1070
+ }
1014
1071
execute_commands (commands , unpack_status );
1015
1072
if (pack_lockfile )
1016
1073
unlink_or_warn (pack_lockfile );
@@ -1027,8 +1084,11 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
1027
1084
}
1028
1085
if (auto_update_server_info )
1029
1086
update_server_info (0 );
1087
+ clear_shallow_info (& si );
1030
1088
}
1031
1089
if (use_sideband )
1032
1090
packet_flush (1 );
1091
+ sha1_array_clear (& shallow );
1092
+ sha1_array_clear (& ref );
1033
1093
return 0 ;
1034
1094
}
0 commit comments