22#include "pack.h"
33#include "refs.h"
44#include "pkt-line.h"
5+ #include "sideband.h"
56#include "run-command.h"
67#include "exec_cmd.h"
78#include "commit.h"
@@ -27,11 +28,12 @@ static int receive_unpack_limit = -1;
2728static int transfer_unpack_limit = -1 ;
2829static int unpack_limit = 100 ;
2930static int report_status ;
31+ static int use_sideband ;
3032static int prefer_ofs_delta = 1 ;
3133static int auto_update_server_info ;
3234static int auto_gc = 1 ;
3335static const char * head_name ;
34- static char * capabilities_to_send ;
36+ static int sent_capabilities ;
3537
3638static enum deny_action parse_deny_action (const char * var , const char * value )
3739{
@@ -105,19 +107,21 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
105107
106108static int show_ref (const char * path , const unsigned char * sha1 , int flag , void * cb_data )
107109{
108- if (! capabilities_to_send )
110+ if (sent_capabilities )
109111 packet_write (1 , "%s %s\n" , sha1_to_hex (sha1 ), path );
110112 else
111- packet_write (1 , "%s %s%c%s\n" ,
112- sha1_to_hex (sha1 ), path , 0 , capabilities_to_send );
113- capabilities_to_send = NULL ;
113+ packet_write (1 , "%s %s%c%s%s\n" ,
114+ sha1_to_hex (sha1 ), path , 0 ,
115+ " report-status delete-refs side-band-64k" ,
116+ prefer_ofs_delta ? " ofs-delta" : "" );
117+ sent_capabilities = 1 ;
114118 return 0 ;
115119}
116120
117121static void write_head_info (void )
118122{
119123 for_each_ref (show_ref , NULL );
120- if (capabilities_to_send )
124+ if (! sent_capabilities )
121125 show_ref ("capabilities^{}" , null_sha1 , 0 , NULL );
122126
123127}
@@ -135,11 +139,25 @@ static struct command *commands;
135139static const char pre_receive_hook [] = "hooks/pre-receive" ;
136140static const char post_receive_hook [] = "hooks/post-receive" ;
137141
142+ static int copy_to_sideband (int in , int out , void * arg )
143+ {
144+ char data [128 ];
145+ while (1 ) {
146+ ssize_t sz = xread (in , data , sizeof (data ));
147+ if (sz <= 0 )
148+ break ;
149+ send_sideband (1 , 2 , data , sz , use_sideband );
150+ }
151+ close (in );
152+ return 0 ;
153+ }
154+
138155static int run_receive_hook (const char * hook_name )
139156{
140157 static char buf [sizeof (commands -> old_sha1 ) * 2 + PATH_MAX + 4 ];
141158 struct command * cmd ;
142159 struct child_process proc ;
160+ struct async muxer ;
143161 const char * argv [2 ];
144162 int have_input = 0 , code ;
145163
@@ -159,9 +177,23 @@ static int run_receive_hook(const char *hook_name)
159177 proc .in = -1 ;
160178 proc .stdout_to_stderr = 1 ;
161179
180+ if (use_sideband ) {
181+ memset (& muxer , 0 , sizeof (muxer ));
182+ muxer .proc = copy_to_sideband ;
183+ muxer .in = -1 ;
184+ code = start_async (& muxer );
185+ if (code )
186+ return code ;
187+ proc .err = muxer .in ;
188+ }
189+
162190 code = start_command (& proc );
163- if (code )
191+ if (code ) {
192+ if (use_sideband )
193+ finish_async (& muxer );
164194 return code ;
195+ }
196+
165197 for (cmd = commands ; cmd ; cmd = cmd -> next ) {
166198 if (!cmd -> error_string ) {
167199 size_t n = snprintf (buf , sizeof (buf ), "%s %s %s\n" ,
@@ -173,13 +205,17 @@ static int run_receive_hook(const char *hook_name)
173205 }
174206 }
175207 close (proc .in );
208+ if (use_sideband )
209+ finish_async (& muxer );
176210 return finish_command (& proc );
177211}
178212
179213static int run_update_hook (struct command * cmd )
180214{
181215 static const char update_hook [] = "hooks/update" ;
182216 const char * argv [5 ];
217+ struct child_process proc ;
218+ int code ;
183219
184220 if (access (update_hook , X_OK ) < 0 )
185221 return 0 ;
@@ -190,8 +226,18 @@ static int run_update_hook(struct command *cmd)
190226 argv [3 ] = sha1_to_hex (cmd -> new_sha1 );
191227 argv [4 ] = NULL ;
192228
193- return run_command_v_opt (argv , RUN_COMMAND_NO_STDIN |
194- RUN_COMMAND_STDOUT_TO_STDERR );
229+ memset (& proc , 0 , sizeof (proc ));
230+ proc .no_stdin = 1 ;
231+ proc .stdout_to_stderr = 1 ;
232+ proc .err = use_sideband ? -1 : 0 ;
233+ proc .argv = argv ;
234+
235+ code = start_command (& proc );
236+ if (code )
237+ return code ;
238+ if (use_sideband )
239+ copy_to_sideband (proc .err , -1 , NULL );
240+ return finish_command (& proc );
195241}
196242
197243static int is_ref_checked_out (const char * ref )
@@ -368,8 +414,9 @@ static char update_post_hook[] = "hooks/post-update";
368414static void run_update_post_hook (struct command * cmd )
369415{
370416 struct command * cmd_p ;
371- int argc , status ;
417+ int argc ;
372418 const char * * argv ;
419+ struct child_process proc ;
373420
374421 for (argc = 0 , cmd_p = cmd ; cmd_p ; cmd_p = cmd_p -> next ) {
375422 if (cmd_p -> error_string )
@@ -391,8 +438,18 @@ static void run_update_post_hook(struct command *cmd)
391438 argc ++ ;
392439 }
393440 argv [argc ] = NULL ;
394- status = run_command_v_opt (argv , RUN_COMMAND_NO_STDIN
395- | RUN_COMMAND_STDOUT_TO_STDERR );
441+
442+ memset (& proc , 0 , sizeof (proc ));
443+ proc .no_stdin = 1 ;
444+ proc .stdout_to_stderr = 1 ;
445+ proc .err = use_sideband ? -1 : 0 ;
446+ proc .argv = argv ;
447+
448+ if (!start_command (& proc )) {
449+ if (use_sideband )
450+ copy_to_sideband (proc .err , -1 , NULL );
451+ finish_command (& proc );
452+ }
396453}
397454
398455static void execute_commands (const char * unpacker_error )
@@ -452,6 +509,8 @@ static void read_head_info(void)
452509 if (reflen + 82 < len ) {
453510 if (strstr (refname + reflen + 1 , "report-status" ))
454511 report_status = 1 ;
512+ if (strstr (refname + reflen + 1 , "side-band-64k" ))
513+ use_sideband = LARGE_PACKET_MAX ;
455514 }
456515 cmd = xmalloc (sizeof (struct command ) + len - 80 );
457516 hashcpy (cmd -> old_sha1 , old_sha1 );
@@ -551,17 +610,25 @@ static const char *unpack(void)
551610static void report (const char * unpack_status )
552611{
553612 struct command * cmd ;
554- packet_write (1 , "unpack %s\n" ,
555- unpack_status ? unpack_status : "ok" );
613+ struct strbuf buf = STRBUF_INIT ;
614+
615+ packet_buf_write (& buf , "unpack %s\n" ,
616+ unpack_status ? unpack_status : "ok" );
556617 for (cmd = commands ; cmd ; cmd = cmd -> next ) {
557618 if (!cmd -> error_string )
558- packet_write ( 1 , "ok %s\n" ,
559- cmd -> ref_name );
619+ packet_buf_write ( & buf , "ok %s\n" ,
620+ cmd -> ref_name );
560621 else
561- packet_write ( 1 , "ng %s %s\n" ,
562- cmd -> ref_name , cmd -> error_string );
622+ packet_buf_write ( & buf , "ng %s %s\n" ,
623+ cmd -> ref_name , cmd -> error_string );
563624 }
564- packet_flush (1 );
625+ packet_buf_flush (& buf );
626+
627+ if (use_sideband )
628+ send_sideband (1 , 1 , buf .buf , buf .len , use_sideband );
629+ else
630+ safe_write (1 , buf .buf , buf .len );
631+ strbuf_release (& buf );
565632}
566633
567634static int delete_only (struct command * cmd )
@@ -658,10 +725,6 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
658725 else if (0 <= receive_unpack_limit )
659726 unpack_limit = receive_unpack_limit ;
660727
661- capabilities_to_send = (prefer_ofs_delta ) ?
662- " report-status delete-refs ofs-delta " :
663- " report-status delete-refs " ;
664-
665728 if (advertise_refs || !stateless_rpc ) {
666729 add_alternate_refs ();
667730 write_head_info ();
@@ -695,5 +758,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
695758 if (auto_update_server_info )
696759 update_server_info (0 );
697760 }
761+ if (use_sideband )
762+ packet_flush (1 );
698763 return 0 ;
699764}
0 commit comments