receive-pack: Send hook output over side band #2
[git] / builtin-receive-pack.c
1 #include "cache.h"
2 #include "pack.h"
3 #include "refs.h"
4 #include "pkt-line.h"
5 #include "sideband.h"
6 #include "run-command.h"
7 #include "exec_cmd.h"
8 #include "commit.h"
9 #include "object.h"
10 #include "remote.h"
11 #include "transport.h"
12
13 static const char receive_pack_usage[] = "git receive-pack <git-dir>";
14
15 enum deny_action {
16         DENY_UNCONFIGURED,
17         DENY_IGNORE,
18         DENY_WARN,
19         DENY_REFUSE,
20 };
21
22 static int deny_deletes;
23 static int deny_non_fast_forwards;
24 static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
25 static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
26 static int receive_fsck_objects;
27 static int receive_unpack_limit = -1;
28 static int transfer_unpack_limit = -1;
29 static int unpack_limit = 100;
30 static int report_status;
31 static int use_sideband;
32 static int prefer_ofs_delta = 1;
33 static int auto_update_server_info;
34 static int auto_gc = 1;
35 static const char *head_name;
36 static int sent_capabilities;
37
38 static enum deny_action parse_deny_action(const char *var, const char *value)
39 {
40         if (value) {
41                 if (!strcasecmp(value, "ignore"))
42                         return DENY_IGNORE;
43                 if (!strcasecmp(value, "warn"))
44                         return DENY_WARN;
45                 if (!strcasecmp(value, "refuse"))
46                         return DENY_REFUSE;
47         }
48         if (git_config_bool(var, value))
49                 return DENY_REFUSE;
50         return DENY_IGNORE;
51 }
52
53 static int receive_pack_config(const char *var, const char *value, void *cb)
54 {
55         if (strcmp(var, "receive.denydeletes") == 0) {
56                 deny_deletes = git_config_bool(var, value);
57                 return 0;
58         }
59
60         if (strcmp(var, "receive.denynonfastforwards") == 0) {
61                 deny_non_fast_forwards = git_config_bool(var, value);
62                 return 0;
63         }
64
65         if (strcmp(var, "receive.unpacklimit") == 0) {
66                 receive_unpack_limit = git_config_int(var, value);
67                 return 0;
68         }
69
70         if (strcmp(var, "transfer.unpacklimit") == 0) {
71                 transfer_unpack_limit = git_config_int(var, value);
72                 return 0;
73         }
74
75         if (strcmp(var, "receive.fsckobjects") == 0) {
76                 receive_fsck_objects = git_config_bool(var, value);
77                 return 0;
78         }
79
80         if (!strcmp(var, "receive.denycurrentbranch")) {
81                 deny_current_branch = parse_deny_action(var, value);
82                 return 0;
83         }
84
85         if (strcmp(var, "receive.denydeletecurrent") == 0) {
86                 deny_delete_current = parse_deny_action(var, value);
87                 return 0;
88         }
89
90         if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
91                 prefer_ofs_delta = git_config_bool(var, value);
92                 return 0;
93         }
94
95         if (strcmp(var, "receive.updateserverinfo") == 0) {
96                 auto_update_server_info = git_config_bool(var, value);
97                 return 0;
98         }
99
100         if (strcmp(var, "receive.autogc") == 0) {
101                 auto_gc = git_config_bool(var, value);
102                 return 0;
103         }
104
105         return git_default_config(var, value, cb);
106 }
107
108 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
109 {
110         if (sent_capabilities)
111                 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
112         else
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;
118         return 0;
119 }
120
121 static void write_head_info(void)
122 {
123         for_each_ref(show_ref, NULL);
124         if (!sent_capabilities)
125                 show_ref("capabilities^{}", null_sha1, 0, NULL);
126
127 }
128
129 struct command {
130         struct command *next;
131         const char *error_string;
132         unsigned char old_sha1[20];
133         unsigned char new_sha1[20];
134         char ref_name[FLEX_ARRAY]; /* more */
135 };
136
137 static struct command *commands;
138
139 static const char pre_receive_hook[] = "hooks/pre-receive";
140 static const char post_receive_hook[] = "hooks/post-receive";
141
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
155 static int run_receive_hook(const char *hook_name)
156 {
157         static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
158         struct command *cmd;
159         struct child_process proc;
160         struct async muxer;
161         const char *argv[2];
162         int have_input = 0, code;
163
164         for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
165                 if (!cmd->error_string)
166                         have_input = 1;
167         }
168
169         if (!have_input || access(hook_name, X_OK) < 0)
170                 return 0;
171
172         argv[0] = hook_name;
173         argv[1] = NULL;
174
175         memset(&proc, 0, sizeof(proc));
176         proc.argv = argv;
177         proc.in = -1;
178         proc.stdout_to_stderr = 1;
179
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
190         code = start_command(&proc);
191         if (code) {
192                 if (use_sideband)
193                         finish_async(&muxer);
194                 return code;
195         }
196
197         for (cmd = commands; cmd; cmd = cmd->next) {
198                 if (!cmd->error_string) {
199                         size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
200                                 sha1_to_hex(cmd->old_sha1),
201                                 sha1_to_hex(cmd->new_sha1),
202                                 cmd->ref_name);
203                         if (write_in_full(proc.in, buf, n) != n)
204                                 break;
205                 }
206         }
207         close(proc.in);
208         if (use_sideband)
209                 finish_async(&muxer);
210         return finish_command(&proc);
211 }
212
213 static int run_update_hook(struct command *cmd)
214 {
215         static const char update_hook[] = "hooks/update";
216         const char *argv[5];
217         struct child_process proc;
218         int code;
219
220         if (access(update_hook, X_OK) < 0)
221                 return 0;
222
223         argv[0] = update_hook;
224         argv[1] = cmd->ref_name;
225         argv[2] = sha1_to_hex(cmd->old_sha1);
226         argv[3] = sha1_to_hex(cmd->new_sha1);
227         argv[4] = NULL;
228
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);
241 }
242
243 static int is_ref_checked_out(const char *ref)
244 {
245         if (is_bare_repository())
246                 return 0;
247
248         if (!head_name)
249                 return 0;
250         return !strcmp(head_name, ref);
251 }
252
253 static char *warn_unconfigured_deny_msg[] = {
254         "Updating the currently checked out branch may cause confusion,",
255         "as the index and work tree do not reflect changes that are in HEAD.",
256         "As a result, you may see the changes you just pushed into it",
257         "reverted when you run 'git diff' over there, and you may want",
258         "to run 'git reset --hard' before starting to work to recover.",
259         "",
260         "You can set 'receive.denyCurrentBranch' configuration variable to",
261         "'refuse' in the remote repository to forbid pushing into its",
262         "current branch."
263         "",
264         "To allow pushing into the current branch, you can set it to 'ignore';",
265         "but this is not recommended unless you arranged to update its work",
266         "tree to match what you pushed in some other way.",
267         "",
268         "To squelch this message, you can set it to 'warn'.",
269         "",
270         "Note that the default will change in a future version of git",
271         "to refuse updating the current branch unless you have the",
272         "configuration variable set to either 'ignore' or 'warn'."
273 };
274
275 static void warn_unconfigured_deny(void)
276 {
277         int i;
278         for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
279                 warning("%s", warn_unconfigured_deny_msg[i]);
280 }
281
282 static char *warn_unconfigured_deny_delete_current_msg[] = {
283         "Deleting the current branch can cause confusion by making the next",
284         "'git clone' not check out any file.",
285         "",
286         "You can set 'receive.denyDeleteCurrent' configuration variable to",
287         "'refuse' in the remote repository to disallow deleting the current",
288         "branch.",
289         "",
290         "You can set it to 'ignore' to allow such a delete without a warning.",
291         "",
292         "To make this warning message less loud, you can set it to 'warn'.",
293         "",
294         "Note that the default will change in a future version of git",
295         "to refuse deleting the current branch unless you have the",
296         "configuration variable set to either 'ignore' or 'warn'."
297 };
298
299 static void warn_unconfigured_deny_delete_current(void)
300 {
301         int i;
302         for (i = 0;
303              i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
304              i++)
305                 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
306 }
307
308 static const char *update(struct command *cmd)
309 {
310         const char *name = cmd->ref_name;
311         unsigned char *old_sha1 = cmd->old_sha1;
312         unsigned char *new_sha1 = cmd->new_sha1;
313         struct ref_lock *lock;
314
315         /* only refs/... are allowed */
316         if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
317                 error("refusing to create funny ref '%s' remotely", name);
318                 return "funny refname";
319         }
320
321         if (is_ref_checked_out(name)) {
322                 switch (deny_current_branch) {
323                 case DENY_IGNORE:
324                         break;
325                 case DENY_UNCONFIGURED:
326                 case DENY_WARN:
327                         warning("updating the current branch");
328                         if (deny_current_branch == DENY_UNCONFIGURED)
329                                 warn_unconfigured_deny();
330                         break;
331                 case DENY_REFUSE:
332                         error("refusing to update checked out branch: %s", name);
333                         return "branch is currently checked out";
334                 }
335         }
336
337         if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
338                 error("unpack should have generated %s, "
339                       "but I can't find it!", sha1_to_hex(new_sha1));
340                 return "bad pack";
341         }
342
343         if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
344                 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
345                         error("denying ref deletion for %s", name);
346                         return "deletion prohibited";
347                 }
348
349                 if (!strcmp(name, head_name)) {
350                         switch (deny_delete_current) {
351                         case DENY_IGNORE:
352                                 break;
353                         case DENY_WARN:
354                         case DENY_UNCONFIGURED:
355                                 if (deny_delete_current == DENY_UNCONFIGURED)
356                                         warn_unconfigured_deny_delete_current();
357                                 warning("deleting the current branch");
358                                 break;
359                         case DENY_REFUSE:
360                                 error("refusing to delete the current branch: %s", name);
361                                 return "deletion of the current branch prohibited";
362                         }
363                 }
364         }
365
366         if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
367             !is_null_sha1(old_sha1) &&
368             !prefixcmp(name, "refs/heads/")) {
369                 struct object *old_object, *new_object;
370                 struct commit *old_commit, *new_commit;
371                 struct commit_list *bases, *ent;
372
373                 old_object = parse_object(old_sha1);
374                 new_object = parse_object(new_sha1);
375
376                 if (!old_object || !new_object ||
377                     old_object->type != OBJ_COMMIT ||
378                     new_object->type != OBJ_COMMIT) {
379                         error("bad sha1 objects for %s", name);
380                         return "bad ref";
381                 }
382                 old_commit = (struct commit *)old_object;
383                 new_commit = (struct commit *)new_object;
384                 bases = get_merge_bases(old_commit, new_commit, 1);
385                 for (ent = bases; ent; ent = ent->next)
386                         if (!hashcmp(old_sha1, ent->item->object.sha1))
387                                 break;
388                 free_commit_list(bases);
389                 if (!ent) {
390                         error("denying non-fast-forward %s"
391                               " (you should pull first)", name);
392                         return "non-fast-forward";
393                 }
394         }
395         if (run_update_hook(cmd)) {
396                 error("hook declined to update %s", name);
397                 return "hook declined";
398         }
399
400         if (is_null_sha1(new_sha1)) {
401                 if (!parse_object(old_sha1)) {
402                         warning ("Allowing deletion of corrupt ref.");
403                         old_sha1 = NULL;
404                 }
405                 if (delete_ref(name, old_sha1, 0)) {
406                         error("failed to delete %s", name);
407                         return "failed to delete";
408                 }
409                 return NULL; /* good */
410         }
411         else {
412                 lock = lock_any_ref_for_update(name, old_sha1, 0);
413                 if (!lock) {
414                         error("failed to lock %s", name);
415                         return "failed to lock";
416                 }
417                 if (write_ref_sha1(lock, new_sha1, "push")) {
418                         return "failed to write"; /* error() already called */
419                 }
420                 return NULL; /* good */
421         }
422 }
423
424 static char update_post_hook[] = "hooks/post-update";
425
426 static void run_update_post_hook(struct command *cmd)
427 {
428         struct command *cmd_p;
429         int argc;
430         const char **argv;
431         struct child_process proc;
432
433         for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
434                 if (cmd_p->error_string)
435                         continue;
436                 argc++;
437         }
438         if (!argc || access(update_post_hook, X_OK) < 0)
439                 return;
440         argv = xmalloc(sizeof(*argv) * (2 + argc));
441         argv[0] = update_post_hook;
442
443         for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
444                 char *p;
445                 if (cmd_p->error_string)
446                         continue;
447                 p = xmalloc(strlen(cmd_p->ref_name) + 1);
448                 strcpy(p, cmd_p->ref_name);
449                 argv[argc] = p;
450                 argc++;
451         }
452         argv[argc] = NULL;
453
454         memset(&proc, 0, sizeof(proc));
455         proc.no_stdin = 1;
456         proc.stdout_to_stderr = 1;
457         proc.err = use_sideband ? -1 : 0;
458         proc.argv = argv;
459
460         if (!start_command(&proc)) {
461                 if (use_sideband)
462                         copy_to_sideband(proc.err, -1, NULL);
463                 finish_command(&proc);
464         }
465 }
466
467 static void execute_commands(const char *unpacker_error)
468 {
469         struct command *cmd = commands;
470         unsigned char sha1[20];
471
472         if (unpacker_error) {
473                 while (cmd) {
474                         cmd->error_string = "n/a (unpacker error)";
475                         cmd = cmd->next;
476                 }
477                 return;
478         }
479
480         if (run_receive_hook(pre_receive_hook)) {
481                 while (cmd) {
482                         cmd->error_string = "pre-receive hook declined";
483                         cmd = cmd->next;
484                 }
485                 return;
486         }
487
488         head_name = resolve_ref("HEAD", sha1, 0, NULL);
489
490         while (cmd) {
491                 cmd->error_string = update(cmd);
492                 cmd = cmd->next;
493         }
494 }
495
496 static void read_head_info(void)
497 {
498         struct command **p = &commands;
499         for (;;) {
500                 static char line[1000];
501                 unsigned char old_sha1[20], new_sha1[20];
502                 struct command *cmd;
503                 char *refname;
504                 int len, reflen;
505
506                 len = packet_read_line(0, line, sizeof(line));
507                 if (!len)
508                         break;
509                 if (line[len-1] == '\n')
510                         line[--len] = 0;
511                 if (len < 83 ||
512                     line[40] != ' ' ||
513                     line[81] != ' ' ||
514                     get_sha1_hex(line, old_sha1) ||
515                     get_sha1_hex(line + 41, new_sha1))
516                         die("protocol error: expected old/new/ref, got '%s'",
517                             line);
518
519                 refname = line + 82;
520                 reflen = strlen(refname);
521                 if (reflen + 82 < len) {
522                         if (strstr(refname + reflen + 1, "report-status"))
523                                 report_status = 1;
524                         if (strstr(refname + reflen + 1, "side-band-64k"))
525                                 use_sideband = LARGE_PACKET_MAX;
526                 }
527                 cmd = xmalloc(sizeof(struct command) + len - 80);
528                 hashcpy(cmd->old_sha1, old_sha1);
529                 hashcpy(cmd->new_sha1, new_sha1);
530                 memcpy(cmd->ref_name, line + 82, len - 81);
531                 cmd->error_string = NULL;
532                 cmd->next = NULL;
533                 *p = cmd;
534                 p = &cmd->next;
535         }
536 }
537
538 static const char *parse_pack_header(struct pack_header *hdr)
539 {
540         switch (read_pack_header(0, hdr)) {
541         case PH_ERROR_EOF:
542                 return "eof before pack header was fully read";
543
544         case PH_ERROR_PACK_SIGNATURE:
545                 return "protocol error (pack signature mismatch detected)";
546
547         case PH_ERROR_PROTOCOL:
548                 return "protocol error (pack version unsupported)";
549
550         default:
551                 return "unknown error in parse_pack_header";
552
553         case 0:
554                 return NULL;
555         }
556 }
557
558 static const char *pack_lockfile;
559
560 static const char *unpack(void)
561 {
562         struct pack_header hdr;
563         const char *hdr_err;
564         char hdr_arg[38];
565
566         hdr_err = parse_pack_header(&hdr);
567         if (hdr_err)
568                 return hdr_err;
569         snprintf(hdr_arg, sizeof(hdr_arg),
570                         "--pack_header=%"PRIu32",%"PRIu32,
571                         ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
572
573         if (ntohl(hdr.hdr_entries) < unpack_limit) {
574                 int code, i = 0;
575                 const char *unpacker[4];
576                 unpacker[i++] = "unpack-objects";
577                 if (receive_fsck_objects)
578                         unpacker[i++] = "--strict";
579                 unpacker[i++] = hdr_arg;
580                 unpacker[i++] = NULL;
581                 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
582                 if (!code)
583                         return NULL;
584                 return "unpack-objects abnormal exit";
585         } else {
586                 const char *keeper[7];
587                 int s, status, i = 0;
588                 char keep_arg[256];
589                 struct child_process ip;
590
591                 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
592                 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
593                         strcpy(keep_arg + s, "localhost");
594
595                 keeper[i++] = "index-pack";
596                 keeper[i++] = "--stdin";
597                 if (receive_fsck_objects)
598                         keeper[i++] = "--strict";
599                 keeper[i++] = "--fix-thin";
600                 keeper[i++] = hdr_arg;
601                 keeper[i++] = keep_arg;
602                 keeper[i++] = NULL;
603                 memset(&ip, 0, sizeof(ip));
604                 ip.argv = keeper;
605                 ip.out = -1;
606                 ip.git_cmd = 1;
607                 status = start_command(&ip);
608                 if (status) {
609                         return "index-pack fork failed";
610                 }
611                 pack_lockfile = index_pack_lockfile(ip.out);
612                 close(ip.out);
613                 status = finish_command(&ip);
614                 if (!status) {
615                         reprepare_packed_git();
616                         return NULL;
617                 }
618                 return "index-pack abnormal exit";
619         }
620 }
621
622 static void report(const char *unpack_status)
623 {
624         struct command *cmd;
625         struct strbuf buf = STRBUF_INIT;
626
627         packet_buf_write(&buf, "unpack %s\n",
628                          unpack_status ? unpack_status : "ok");
629         for (cmd = commands; cmd; cmd = cmd->next) {
630                 if (!cmd->error_string)
631                         packet_buf_write(&buf, "ok %s\n",
632                                          cmd->ref_name);
633                 else
634                         packet_buf_write(&buf, "ng %s %s\n",
635                                          cmd->ref_name, cmd->error_string);
636         }
637         packet_buf_flush(&buf);
638
639         if (use_sideband)
640                 send_sideband(1, 1, buf.buf, buf.len, use_sideband);
641         else
642                 safe_write(1, buf.buf, buf.len);
643         strbuf_release(&buf);
644 }
645
646 static int delete_only(struct command *cmd)
647 {
648         while (cmd) {
649                 if (!is_null_sha1(cmd->new_sha1))
650                         return 0;
651                 cmd = cmd->next;
652         }
653         return 1;
654 }
655
656 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
657 {
658         char *other;
659         size_t len;
660         struct remote *remote;
661         struct transport *transport;
662         const struct ref *extra;
663
664         e->name[-1] = '\0';
665         other = xstrdup(make_absolute_path(e->base));
666         e->name[-1] = '/';
667         len = strlen(other);
668
669         while (other[len-1] == '/')
670                 other[--len] = '\0';
671         if (len < 8 || memcmp(other + len - 8, "/objects", 8))
672                 return 0;
673         /* Is this a git repository with refs? */
674         memcpy(other + len - 8, "/refs", 6);
675         if (!is_directory(other))
676                 return 0;
677         other[len - 8] = '\0';
678         remote = remote_get(other);
679         transport = transport_get(remote, other);
680         for (extra = transport_get_remote_refs(transport);
681              extra;
682              extra = extra->next) {
683                 add_extra_ref(".have", extra->old_sha1, 0);
684         }
685         transport_disconnect(transport);
686         free(other);
687         return 0;
688 }
689
690 static void add_alternate_refs(void)
691 {
692         foreach_alt_odb(add_refs_from_alternate, NULL);
693 }
694
695 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
696 {
697         int advertise_refs = 0;
698         int stateless_rpc = 0;
699         int i;
700         char *dir = NULL;
701
702         argv++;
703         for (i = 1; i < argc; i++) {
704                 const char *arg = *argv++;
705
706                 if (*arg == '-') {
707                         if (!strcmp(arg, "--advertise-refs")) {
708                                 advertise_refs = 1;
709                                 continue;
710                         }
711                         if (!strcmp(arg, "--stateless-rpc")) {
712                                 stateless_rpc = 1;
713                                 continue;
714                         }
715
716                         usage(receive_pack_usage);
717                 }
718                 if (dir)
719                         usage(receive_pack_usage);
720                 dir = xstrdup(arg);
721         }
722         if (!dir)
723                 usage(receive_pack_usage);
724
725         setup_path();
726
727         if (!enter_repo(dir, 0))
728                 die("'%s' does not appear to be a git repository", dir);
729
730         if (is_repository_shallow())
731                 die("attempt to push into a shallow repository");
732
733         git_config(receive_pack_config, NULL);
734
735         if (0 <= transfer_unpack_limit)
736                 unpack_limit = transfer_unpack_limit;
737         else if (0 <= receive_unpack_limit)
738                 unpack_limit = receive_unpack_limit;
739
740         if (advertise_refs || !stateless_rpc) {
741                 add_alternate_refs();
742                 write_head_info();
743                 clear_extra_refs();
744
745                 /* EOF */
746                 packet_flush(1);
747         }
748         if (advertise_refs)
749                 return 0;
750
751         read_head_info();
752         if (commands) {
753                 const char *unpack_status = NULL;
754
755                 if (!delete_only(commands))
756                         unpack_status = unpack();
757                 execute_commands(unpack_status);
758                 if (pack_lockfile)
759                         unlink_or_warn(pack_lockfile);
760                 if (report_status)
761                         report(unpack_status);
762                 run_receive_hook(post_receive_hook);
763                 run_update_post_hook(commands);
764                 if (auto_gc) {
765                         const char *argv_gc_auto[] = {
766                                 "gc", "--auto", "--quiet", NULL,
767                         };
768                         run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
769                 }
770                 if (auto_update_server_info)
771                         update_server_info(0);
772         }
773         if (use_sideband)
774                 packet_flush(1);
775         return 0;
776 }