Code

receive-pack: Wrap status reports inside side-band-64k
[git.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"
13 static const char receive_pack_usage[] = "git receive-pack <git-dir>";
15 enum deny_action {
16         DENY_UNCONFIGURED,
17         DENY_IGNORE,
18         DENY_WARN,
19         DENY_REFUSE,
20 };
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;
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 }
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         }
60         if (strcmp(var, "receive.denynonfastforwards") == 0) {
61                 deny_non_fast_forwards = git_config_bool(var, value);
62                 return 0;
63         }
65         if (strcmp(var, "receive.unpacklimit") == 0) {
66                 receive_unpack_limit = git_config_int(var, value);
67                 return 0;
68         }
70         if (strcmp(var, "transfer.unpacklimit") == 0) {
71                 transfer_unpack_limit = git_config_int(var, value);
72                 return 0;
73         }
75         if (strcmp(var, "receive.fsckobjects") == 0) {
76                 receive_fsck_objects = git_config_bool(var, value);
77                 return 0;
78         }
80         if (!strcmp(var, "receive.denycurrentbranch")) {
81                 deny_current_branch = parse_deny_action(var, value);
82                 return 0;
83         }
85         if (strcmp(var, "receive.denydeletecurrent") == 0) {
86                 deny_delete_current = parse_deny_action(var, value);
87                 return 0;
88         }
90         if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
91                 prefer_ofs_delta = git_config_bool(var, value);
92                 return 0;
93         }
95         if (strcmp(var, "receive.updateserverinfo") == 0) {
96                 auto_update_server_info = git_config_bool(var, value);
97                 return 0;
98         }
100         if (strcmp(var, "receive.autogc") == 0) {
101                 auto_gc = git_config_bool(var, value);
102                 return 0;
103         }
105         return git_default_config(var, value, cb);
108 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
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;
121 static void write_head_info(void)
123         for_each_ref(show_ref, NULL);
124         if (!sent_capabilities)
125                 show_ref("capabilities^{}", null_sha1, 0, NULL);
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 };
137 static struct command *commands;
139 static const char pre_receive_hook[] = "hooks/pre-receive";
140 static const char post_receive_hook[] = "hooks/post-receive";
142 static int run_receive_hook(const char *hook_name)
144         static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
145         struct command *cmd;
146         struct child_process proc;
147         const char *argv[2];
148         int have_input = 0, code;
150         for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
151                 if (!cmd->error_string)
152                         have_input = 1;
153         }
155         if (!have_input || access(hook_name, X_OK) < 0)
156                 return 0;
158         argv[0] = hook_name;
159         argv[1] = NULL;
161         memset(&proc, 0, sizeof(proc));
162         proc.argv = argv;
163         proc.in = -1;
164         proc.stdout_to_stderr = 1;
166         code = start_command(&proc);
167         if (code)
168                 return code;
169         for (cmd = commands; cmd; cmd = cmd->next) {
170                 if (!cmd->error_string) {
171                         size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
172                                 sha1_to_hex(cmd->old_sha1),
173                                 sha1_to_hex(cmd->new_sha1),
174                                 cmd->ref_name);
175                         if (write_in_full(proc.in, buf, n) != n)
176                                 break;
177                 }
178         }
179         close(proc.in);
180         return finish_command(&proc);
183 static int run_update_hook(struct command *cmd)
185         static const char update_hook[] = "hooks/update";
186         const char *argv[5];
188         if (access(update_hook, X_OK) < 0)
189                 return 0;
191         argv[0] = update_hook;
192         argv[1] = cmd->ref_name;
193         argv[2] = sha1_to_hex(cmd->old_sha1);
194         argv[3] = sha1_to_hex(cmd->new_sha1);
195         argv[4] = NULL;
197         return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
198                                         RUN_COMMAND_STDOUT_TO_STDERR);
201 static int is_ref_checked_out(const char *ref)
203         if (is_bare_repository())
204                 return 0;
206         if (!head_name)
207                 return 0;
208         return !strcmp(head_name, ref);
211 static char *warn_unconfigured_deny_msg[] = {
212         "Updating the currently checked out branch may cause confusion,",
213         "as the index and work tree do not reflect changes that are in HEAD.",
214         "As a result, you may see the changes you just pushed into it",
215         "reverted when you run 'git diff' over there, and you may want",
216         "to run 'git reset --hard' before starting to work to recover.",
217         "",
218         "You can set 'receive.denyCurrentBranch' configuration variable to",
219         "'refuse' in the remote repository to forbid pushing into its",
220         "current branch."
221         "",
222         "To allow pushing into the current branch, you can set it to 'ignore';",
223         "but this is not recommended unless you arranged to update its work",
224         "tree to match what you pushed in some other way.",
225         "",
226         "To squelch this message, you can set it to 'warn'.",
227         "",
228         "Note that the default will change in a future version of git",
229         "to refuse updating the current branch unless you have the",
230         "configuration variable set to either 'ignore' or 'warn'."
231 };
233 static void warn_unconfigured_deny(void)
235         int i;
236         for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
237                 warning("%s", warn_unconfigured_deny_msg[i]);
240 static char *warn_unconfigured_deny_delete_current_msg[] = {
241         "Deleting the current branch can cause confusion by making the next",
242         "'git clone' not check out any file.",
243         "",
244         "You can set 'receive.denyDeleteCurrent' configuration variable to",
245         "'refuse' in the remote repository to disallow deleting the current",
246         "branch.",
247         "",
248         "You can set it to 'ignore' to allow such a delete without a warning.",
249         "",
250         "To make this warning message less loud, you can set it to 'warn'.",
251         "",
252         "Note that the default will change in a future version of git",
253         "to refuse deleting the current branch unless you have the",
254         "configuration variable set to either 'ignore' or 'warn'."
255 };
257 static void warn_unconfigured_deny_delete_current(void)
259         int i;
260         for (i = 0;
261              i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
262              i++)
263                 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
266 static const char *update(struct command *cmd)
268         const char *name = cmd->ref_name;
269         unsigned char *old_sha1 = cmd->old_sha1;
270         unsigned char *new_sha1 = cmd->new_sha1;
271         struct ref_lock *lock;
273         /* only refs/... are allowed */
274         if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
275                 error("refusing to create funny ref '%s' remotely", name);
276                 return "funny refname";
277         }
279         if (is_ref_checked_out(name)) {
280                 switch (deny_current_branch) {
281                 case DENY_IGNORE:
282                         break;
283                 case DENY_UNCONFIGURED:
284                 case DENY_WARN:
285                         warning("updating the current branch");
286                         if (deny_current_branch == DENY_UNCONFIGURED)
287                                 warn_unconfigured_deny();
288                         break;
289                 case DENY_REFUSE:
290                         error("refusing to update checked out branch: %s", name);
291                         return "branch is currently checked out";
292                 }
293         }
295         if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
296                 error("unpack should have generated %s, "
297                       "but I can't find it!", sha1_to_hex(new_sha1));
298                 return "bad pack";
299         }
301         if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
302                 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
303                         error("denying ref deletion for %s", name);
304                         return "deletion prohibited";
305                 }
307                 if (!strcmp(name, head_name)) {
308                         switch (deny_delete_current) {
309                         case DENY_IGNORE:
310                                 break;
311                         case DENY_WARN:
312                         case DENY_UNCONFIGURED:
313                                 if (deny_delete_current == DENY_UNCONFIGURED)
314                                         warn_unconfigured_deny_delete_current();
315                                 warning("deleting the current branch");
316                                 break;
317                         case DENY_REFUSE:
318                                 error("refusing to delete the current branch: %s", name);
319                                 return "deletion of the current branch prohibited";
320                         }
321                 }
322         }
324         if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
325             !is_null_sha1(old_sha1) &&
326             !prefixcmp(name, "refs/heads/")) {
327                 struct object *old_object, *new_object;
328                 struct commit *old_commit, *new_commit;
329                 struct commit_list *bases, *ent;
331                 old_object = parse_object(old_sha1);
332                 new_object = parse_object(new_sha1);
334                 if (!old_object || !new_object ||
335                     old_object->type != OBJ_COMMIT ||
336                     new_object->type != OBJ_COMMIT) {
337                         error("bad sha1 objects for %s", name);
338                         return "bad ref";
339                 }
340                 old_commit = (struct commit *)old_object;
341                 new_commit = (struct commit *)new_object;
342                 bases = get_merge_bases(old_commit, new_commit, 1);
343                 for (ent = bases; ent; ent = ent->next)
344                         if (!hashcmp(old_sha1, ent->item->object.sha1))
345                                 break;
346                 free_commit_list(bases);
347                 if (!ent) {
348                         error("denying non-fast-forward %s"
349                               " (you should pull first)", name);
350                         return "non-fast-forward";
351                 }
352         }
353         if (run_update_hook(cmd)) {
354                 error("hook declined to update %s", name);
355                 return "hook declined";
356         }
358         if (is_null_sha1(new_sha1)) {
359                 if (!parse_object(old_sha1)) {
360                         warning ("Allowing deletion of corrupt ref.");
361                         old_sha1 = NULL;
362                 }
363                 if (delete_ref(name, old_sha1, 0)) {
364                         error("failed to delete %s", name);
365                         return "failed to delete";
366                 }
367                 return NULL; /* good */
368         }
369         else {
370                 lock = lock_any_ref_for_update(name, old_sha1, 0);
371                 if (!lock) {
372                         error("failed to lock %s", name);
373                         return "failed to lock";
374                 }
375                 if (write_ref_sha1(lock, new_sha1, "push")) {
376                         return "failed to write"; /* error() already called */
377                 }
378                 return NULL; /* good */
379         }
382 static char update_post_hook[] = "hooks/post-update";
384 static void run_update_post_hook(struct command *cmd)
386         struct command *cmd_p;
387         int argc, status;
388         const char **argv;
390         for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
391                 if (cmd_p->error_string)
392                         continue;
393                 argc++;
394         }
395         if (!argc || access(update_post_hook, X_OK) < 0)
396                 return;
397         argv = xmalloc(sizeof(*argv) * (2 + argc));
398         argv[0] = update_post_hook;
400         for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
401                 char *p;
402                 if (cmd_p->error_string)
403                         continue;
404                 p = xmalloc(strlen(cmd_p->ref_name) + 1);
405                 strcpy(p, cmd_p->ref_name);
406                 argv[argc] = p;
407                 argc++;
408         }
409         argv[argc] = NULL;
410         status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
411                         | RUN_COMMAND_STDOUT_TO_STDERR);
414 static void execute_commands(const char *unpacker_error)
416         struct command *cmd = commands;
417         unsigned char sha1[20];
419         if (unpacker_error) {
420                 while (cmd) {
421                         cmd->error_string = "n/a (unpacker error)";
422                         cmd = cmd->next;
423                 }
424                 return;
425         }
427         if (run_receive_hook(pre_receive_hook)) {
428                 while (cmd) {
429                         cmd->error_string = "pre-receive hook declined";
430                         cmd = cmd->next;
431                 }
432                 return;
433         }
435         head_name = resolve_ref("HEAD", sha1, 0, NULL);
437         while (cmd) {
438                 cmd->error_string = update(cmd);
439                 cmd = cmd->next;
440         }
443 static void read_head_info(void)
445         struct command **p = &commands;
446         for (;;) {
447                 static char line[1000];
448                 unsigned char old_sha1[20], new_sha1[20];
449                 struct command *cmd;
450                 char *refname;
451                 int len, reflen;
453                 len = packet_read_line(0, line, sizeof(line));
454                 if (!len)
455                         break;
456                 if (line[len-1] == '\n')
457                         line[--len] = 0;
458                 if (len < 83 ||
459                     line[40] != ' ' ||
460                     line[81] != ' ' ||
461                     get_sha1_hex(line, old_sha1) ||
462                     get_sha1_hex(line + 41, new_sha1))
463                         die("protocol error: expected old/new/ref, got '%s'",
464                             line);
466                 refname = line + 82;
467                 reflen = strlen(refname);
468                 if (reflen + 82 < len) {
469                         if (strstr(refname + reflen + 1, "report-status"))
470                                 report_status = 1;
471                         if (strstr(refname + reflen + 1, "side-band-64k"))
472                                 use_sideband = LARGE_PACKET_MAX;
473                 }
474                 cmd = xmalloc(sizeof(struct command) + len - 80);
475                 hashcpy(cmd->old_sha1, old_sha1);
476                 hashcpy(cmd->new_sha1, new_sha1);
477                 memcpy(cmd->ref_name, line + 82, len - 81);
478                 cmd->error_string = NULL;
479                 cmd->next = NULL;
480                 *p = cmd;
481                 p = &cmd->next;
482         }
485 static const char *parse_pack_header(struct pack_header *hdr)
487         switch (read_pack_header(0, hdr)) {
488         case PH_ERROR_EOF:
489                 return "eof before pack header was fully read";
491         case PH_ERROR_PACK_SIGNATURE:
492                 return "protocol error (pack signature mismatch detected)";
494         case PH_ERROR_PROTOCOL:
495                 return "protocol error (pack version unsupported)";
497         default:
498                 return "unknown error in parse_pack_header";
500         case 0:
501                 return NULL;
502         }
505 static const char *pack_lockfile;
507 static const char *unpack(void)
509         struct pack_header hdr;
510         const char *hdr_err;
511         char hdr_arg[38];
513         hdr_err = parse_pack_header(&hdr);
514         if (hdr_err)
515                 return hdr_err;
516         snprintf(hdr_arg, sizeof(hdr_arg),
517                         "--pack_header=%"PRIu32",%"PRIu32,
518                         ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
520         if (ntohl(hdr.hdr_entries) < unpack_limit) {
521                 int code, i = 0;
522                 const char *unpacker[4];
523                 unpacker[i++] = "unpack-objects";
524                 if (receive_fsck_objects)
525                         unpacker[i++] = "--strict";
526                 unpacker[i++] = hdr_arg;
527                 unpacker[i++] = NULL;
528                 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
529                 if (!code)
530                         return NULL;
531                 return "unpack-objects abnormal exit";
532         } else {
533                 const char *keeper[7];
534                 int s, status, i = 0;
535                 char keep_arg[256];
536                 struct child_process ip;
538                 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
539                 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
540                         strcpy(keep_arg + s, "localhost");
542                 keeper[i++] = "index-pack";
543                 keeper[i++] = "--stdin";
544                 if (receive_fsck_objects)
545                         keeper[i++] = "--strict";
546                 keeper[i++] = "--fix-thin";
547                 keeper[i++] = hdr_arg;
548                 keeper[i++] = keep_arg;
549                 keeper[i++] = NULL;
550                 memset(&ip, 0, sizeof(ip));
551                 ip.argv = keeper;
552                 ip.out = -1;
553                 ip.git_cmd = 1;
554                 status = start_command(&ip);
555                 if (status) {
556                         return "index-pack fork failed";
557                 }
558                 pack_lockfile = index_pack_lockfile(ip.out);
559                 close(ip.out);
560                 status = finish_command(&ip);
561                 if (!status) {
562                         reprepare_packed_git();
563                         return NULL;
564                 }
565                 return "index-pack abnormal exit";
566         }
569 static void report(const char *unpack_status)
571         struct command *cmd;
572         struct strbuf buf = STRBUF_INIT;
574         packet_buf_write(&buf, "unpack %s\n",
575                          unpack_status ? unpack_status : "ok");
576         for (cmd = commands; cmd; cmd = cmd->next) {
577                 if (!cmd->error_string)
578                         packet_buf_write(&buf, "ok %s\n",
579                                          cmd->ref_name);
580                 else
581                         packet_buf_write(&buf, "ng %s %s\n",
582                                          cmd->ref_name, cmd->error_string);
583         }
584         packet_buf_flush(&buf);
586         if (use_sideband)
587                 send_sideband(1, 1, buf.buf, buf.len, use_sideband);
588         else
589                 safe_write(1, buf.buf, buf.len);
590         strbuf_release(&buf);
593 static int delete_only(struct command *cmd)
595         while (cmd) {
596                 if (!is_null_sha1(cmd->new_sha1))
597                         return 0;
598                 cmd = cmd->next;
599         }
600         return 1;
603 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
605         char *other;
606         size_t len;
607         struct remote *remote;
608         struct transport *transport;
609         const struct ref *extra;
611         e->name[-1] = '\0';
612         other = xstrdup(make_absolute_path(e->base));
613         e->name[-1] = '/';
614         len = strlen(other);
616         while (other[len-1] == '/')
617                 other[--len] = '\0';
618         if (len < 8 || memcmp(other + len - 8, "/objects", 8))
619                 return 0;
620         /* Is this a git repository with refs? */
621         memcpy(other + len - 8, "/refs", 6);
622         if (!is_directory(other))
623                 return 0;
624         other[len - 8] = '\0';
625         remote = remote_get(other);
626         transport = transport_get(remote, other);
627         for (extra = transport_get_remote_refs(transport);
628              extra;
629              extra = extra->next) {
630                 add_extra_ref(".have", extra->old_sha1, 0);
631         }
632         transport_disconnect(transport);
633         free(other);
634         return 0;
637 static void add_alternate_refs(void)
639         foreach_alt_odb(add_refs_from_alternate, NULL);
642 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
644         int advertise_refs = 0;
645         int stateless_rpc = 0;
646         int i;
647         char *dir = NULL;
649         argv++;
650         for (i = 1; i < argc; i++) {
651                 const char *arg = *argv++;
653                 if (*arg == '-') {
654                         if (!strcmp(arg, "--advertise-refs")) {
655                                 advertise_refs = 1;
656                                 continue;
657                         }
658                         if (!strcmp(arg, "--stateless-rpc")) {
659                                 stateless_rpc = 1;
660                                 continue;
661                         }
663                         usage(receive_pack_usage);
664                 }
665                 if (dir)
666                         usage(receive_pack_usage);
667                 dir = xstrdup(arg);
668         }
669         if (!dir)
670                 usage(receive_pack_usage);
672         setup_path();
674         if (!enter_repo(dir, 0))
675                 die("'%s' does not appear to be a git repository", dir);
677         if (is_repository_shallow())
678                 die("attempt to push into a shallow repository");
680         git_config(receive_pack_config, NULL);
682         if (0 <= transfer_unpack_limit)
683                 unpack_limit = transfer_unpack_limit;
684         else if (0 <= receive_unpack_limit)
685                 unpack_limit = receive_unpack_limit;
687         if (advertise_refs || !stateless_rpc) {
688                 add_alternate_refs();
689                 write_head_info();
690                 clear_extra_refs();
692                 /* EOF */
693                 packet_flush(1);
694         }
695         if (advertise_refs)
696                 return 0;
698         read_head_info();
699         if (commands) {
700                 const char *unpack_status = NULL;
702                 if (!delete_only(commands))
703                         unpack_status = unpack();
704                 execute_commands(unpack_status);
705                 if (pack_lockfile)
706                         unlink_or_warn(pack_lockfile);
707                 if (report_status)
708                         report(unpack_status);
709                 run_receive_hook(post_receive_hook);
710                 run_update_post_hook(commands);
711                 if (auto_gc) {
712                         const char *argv_gc_auto[] = {
713                                 "gc", "--auto", "--quiet", NULL,
714                         };
715                         run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
716                 }
717                 if (auto_update_server_info)
718                         update_server_info(0);
719         }
720         if (use_sideband)
721                 packet_flush(1);
722         return 0;