@@ -8,20 +8,33 @@ static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
88
99static const char unpacker [] = "git-unpack-objects" ;
1010
11+ static int report_status = 0 ;
12+
13+ static char capabilities [] = "report-status" ;
14+ static int capabilities_sent = 0 ;
15+
1116static int show_ref (const char * path , const unsigned char * sha1 )
1217{
13- packet_write (1 , "%s %s\n" , sha1_to_hex (sha1 ), path );
18+ if (capabilities_sent )
19+ packet_write (1 , "%s %s\n" , sha1_to_hex (sha1 ), path );
20+ else
21+ packet_write (1 , "%s %s%c%s\n" ,
22+ sha1_to_hex (sha1 ), path , 0 , capabilities );
23+ capabilities_sent = 1 ;
1424 return 0 ;
1525}
1626
1727static void write_head_info (void )
1828{
1929 for_each_ref (show_ref );
30+ if (!capabilities_sent )
31+ show_ref ("capabilities^{}" , null_sha1 );
32+
2033}
2134
2235struct command {
2336 struct command * next ;
24- unsigned char updated ;
37+ const char * error_string ;
2538 unsigned char old_sha1 [20 ];
2639 unsigned char new_sha1 [20 ];
2740 char ref_name [0 ];
@@ -71,33 +84,37 @@ static int run_update_hook(const char *refname,
7184 case 0 :
7285 return 0 ;
7386 case - ERR_RUN_COMMAND_FORK :
74- die ("hook fork failed" );
87+ return error ("hook fork failed" );
7588 case - ERR_RUN_COMMAND_EXEC :
76- die ("hook execute failed" );
89+ return error ("hook execute failed" );
7790 case - ERR_RUN_COMMAND_WAITPID :
78- die ("waitpid failed" );
91+ return error ("waitpid failed" );
7992 case - ERR_RUN_COMMAND_WAITPID_WRONG_PID :
80- die ("waitpid is confused" );
93+ return error ("waitpid is confused" );
8194 case - ERR_RUN_COMMAND_WAITPID_SIGNAL :
82- fprintf (stderr , "%s died of signal\n" , update_hook );
83- return -1 ;
95+ return error ("%s died of signal\n" , update_hook );
8496 case - ERR_RUN_COMMAND_WAITPID_NOEXIT :
85- die ("%s died strangely" , update_hook );
97+ return error ("%s died strangely" , update_hook );
8698 default :
8799 error ("%s exited with error code %d" , update_hook , - code );
88100 return - code ;
89101 }
90102}
91103
92- static int update (const char * name ,
93- unsigned char * old_sha1 , unsigned char * new_sha1 )
104+ static int update (struct command * cmd )
94105{
106+ const char * name = cmd -> ref_name ;
107+ unsigned char * old_sha1 = cmd -> old_sha1 ;
108+ unsigned char * new_sha1 = cmd -> new_sha1 ;
95109 char new_hex [60 ], * old_hex , * lock_name ;
96110 int newfd , namelen , written ;
97111
98- if (!strncmp (name , "refs/" , 5 ) && check_ref_format (name + 5 ))
112+ cmd -> error_string = NULL ;
113+ if (!strncmp (name , "refs/" , 5 ) && check_ref_format (name + 5 )) {
114+ cmd -> error_string = "funny refname" ;
99115 return error ("refusing to create funny ref '%s' locally" ,
100116 name );
117+ }
101118
102119 namelen = strlen (name );
103120 lock_name = xmalloc (namelen + 10 );
@@ -106,16 +123,19 @@ static int update(const char *name,
106123
107124 strcpy (new_hex , sha1_to_hex (new_sha1 ));
108125 old_hex = sha1_to_hex (old_sha1 );
109- if (!has_sha1_file (new_sha1 ))
126+ if (!has_sha1_file (new_sha1 )) {
127+ cmd -> error_string = "bad pack" ;
110128 return error ("unpack should have generated %s, "
111129 "but I can't find it!" , new_hex );
112-
130+ }
113131 safe_create_leading_directories (lock_name );
114132
115133 newfd = open (lock_name , O_CREAT | O_EXCL | O_WRONLY , 0666 );
116- if (newfd < 0 )
134+ if (newfd < 0 ) {
135+ cmd -> error_string = "can't lock" ;
117136 return error ("unable to create %s (%s)" ,
118137 lock_name , strerror (errno ));
138+ }
119139
120140 /* Write the ref with an ending '\n' */
121141 new_hex [40 ] = '\n' ;
@@ -127,18 +147,22 @@ static int update(const char *name,
127147 close (newfd );
128148 if (written != 41 ) {
129149 unlink (lock_name );
150+ cmd -> error_string = "can't write" ;
130151 return error ("unable to write %s" , lock_name );
131152 }
132153 if (verify_old_ref (name , old_hex ) < 0 ) {
133154 unlink (lock_name );
155+ cmd -> error_string = "raced" ;
134156 return error ("%s changed during push" , name );
135157 }
136158 if (run_update_hook (name , old_hex , new_hex )) {
137159 unlink (lock_name );
160+ cmd -> error_string = "hook declined" ;
138161 return error ("hook declined to update %s\n" , name );
139162 }
140163 else if (rename (lock_name , name ) < 0 ) {
141164 unlink (lock_name );
165+ cmd -> error_string = "can't rename" ;
142166 return error ("unable to replace %s" , name );
143167 }
144168 else {
@@ -158,15 +182,15 @@ static void run_update_post_hook(struct command *cmd)
158182 if (access (update_post_hook , X_OK ) < 0 )
159183 return ;
160184 for (argc = 1 , cmd_p = cmd ; cmd_p ; cmd_p = cmd_p -> next ) {
161- if (! cmd_p -> updated )
185+ if (cmd_p -> error_string )
162186 continue ;
163187 argc ++ ;
164188 }
165189 argv = xmalloc (sizeof (* argv ) * (1 + argc ));
166190 argv [0 ] = update_post_hook ;
167191
168192 for (argc = 1 , cmd_p = cmd ; cmd_p ; cmd_p = cmd_p -> next ) {
169- if (! cmd_p -> updated )
193+ if (cmd_p -> error_string )
170194 continue ;
171195 argv [argc ] = xmalloc (strlen (cmd_p -> ref_name ) + 1 );
172196 strcpy (argv [argc ], cmd_p -> ref_name );
@@ -185,8 +209,7 @@ static void execute_commands(void)
185209 struct command * cmd = commands ;
186210
187211 while (cmd ) {
188- cmd -> updated = !update (cmd -> ref_name ,
189- cmd -> old_sha1 , cmd -> new_sha1 );
212+ update (cmd );
190213 cmd = cmd -> next ;
191214 }
192215 run_update_post_hook (commands );
@@ -199,7 +222,8 @@ static void read_head_info(void)
199222 static char line [1000 ];
200223 unsigned char old_sha1 [20 ], new_sha1 [20 ];
201224 struct command * cmd ;
202- int len ;
225+ char * refname ;
226+ int len , reflen ;
203227
204228 len = packet_read_line (0 , line , sizeof (line ));
205229 if (!len )
@@ -211,38 +235,66 @@ static void read_head_info(void)
211235 line [81 ] != ' ' ||
212236 get_sha1_hex (line , old_sha1 ) ||
213237 get_sha1_hex (line + 41 , new_sha1 ))
214- die ("protocol error: expected old/new/ref, got '%s'" , line );
238+ die ("protocol error: expected old/new/ref, got '%s'" ,
239+ line );
240+
241+ refname = line + 82 ;
242+ reflen = strlen (refname );
243+ if (reflen + 82 < len ) {
244+ if (strstr (refname + reflen + 1 , "report-status" ))
245+ report_status = 1 ;
246+ }
215247 cmd = xmalloc (sizeof (struct command ) + len - 80 );
216248 memcpy (cmd -> old_sha1 , old_sha1 , 20 );
217249 memcpy (cmd -> new_sha1 , new_sha1 , 20 );
218250 memcpy (cmd -> ref_name , line + 82 , len - 81 );
251+ cmd -> error_string = "n/a (unpacker error)" ;
219252 cmd -> next = NULL ;
220253 * p = cmd ;
221254 p = & cmd -> next ;
222255 }
223256}
224257
225- static void unpack (void )
258+ static const char * unpack (int * error_code )
226259{
227260 int code = run_command (unpacker , NULL );
261+
262+ * error_code = 0 ;
228263 switch (code ) {
229264 case 0 :
230- return ;
265+ return NULL ;
231266 case - ERR_RUN_COMMAND_FORK :
232- die ( "unpack fork failed" ) ;
267+ return "unpack fork failed" ;
233268 case - ERR_RUN_COMMAND_EXEC :
234- die ( "unpack execute failed" ) ;
269+ return "unpack execute failed" ;
235270 case - ERR_RUN_COMMAND_WAITPID :
236- die ( "waitpid failed" ) ;
271+ return "waitpid failed" ;
237272 case - ERR_RUN_COMMAND_WAITPID_WRONG_PID :
238- die ( "waitpid is confused" ) ;
273+ return "waitpid is confused" ;
239274 case - ERR_RUN_COMMAND_WAITPID_SIGNAL :
240- die ( "%s died of signal", unpacker ) ;
275+ return "unpacker died of signal" ;
241276 case - ERR_RUN_COMMAND_WAITPID_NOEXIT :
242- die ( "%s died strangely", unpacker ) ;
277+ return "unpacker died strangely" ;
243278 default :
244- die ("%s exited with error code %d" , unpacker , - code );
279+ * error_code = - code ;
280+ return "unpacker exited with error code" ;
281+ }
282+ }
283+
284+ static void report (const char * unpack_status )
285+ {
286+ struct command * cmd ;
287+ packet_write (1 , "unpack %s\n" ,
288+ unpack_status ? unpack_status : "ok" );
289+ for (cmd = commands ; cmd ; cmd = cmd -> next ) {
290+ if (!cmd -> error_string )
291+ packet_write (1 , "ok %s\n" ,
292+ cmd -> ref_name );
293+ else
294+ packet_write (1 , "ng %s %s\n" ,
295+ cmd -> ref_name , cmd -> error_string );
245296 }
297+ packet_flush (1 );
246298}
247299
248300int main (int argc , char * * argv )
@@ -275,8 +327,12 @@ int main(int argc, char **argv)
275327
276328 read_head_info ();
277329 if (commands ) {
278- unpack ();
279- execute_commands ();
330+ int code ;
331+ const char * unpack_status = unpack (& code );
332+ if (!unpack_status )
333+ execute_commands ();
334+ if (report_status )
335+ report (unpack_status );
280336 }
281337 return 0 ;
282338}
0 commit comments