receive-pack: switch global variable 'commands' to a parameter
[git/dscho.git] / builtin-receive-pack.c
blobfffb6eac881a536ea7fa4a94a0790a117d8b4cf2
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,
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)
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;
48 if (git_config_bool(var, value))
49 return DENY_REFUSE;
50 return DENY_IGNORE;
53 static int receive_pack_config(const char *var, const char *value, void *cb)
55 if (strcmp(var, "receive.denydeletes") == 0) {
56 deny_deletes = git_config_bool(var, value);
57 return 0;
60 if (strcmp(var, "receive.denynonfastforwards") == 0) {
61 deny_non_fast_forwards = git_config_bool(var, value);
62 return 0;
65 if (strcmp(var, "receive.unpacklimit") == 0) {
66 receive_unpack_limit = git_config_int(var, value);
67 return 0;
70 if (strcmp(var, "transfer.unpacklimit") == 0) {
71 transfer_unpack_limit = git_config_int(var, value);
72 return 0;
75 if (strcmp(var, "receive.fsckobjects") == 0) {
76 receive_fsck_objects = git_config_bool(var, value);
77 return 0;
80 if (!strcmp(var, "receive.denycurrentbranch")) {
81 deny_current_branch = parse_deny_action(var, value);
82 return 0;
85 if (strcmp(var, "receive.denydeletecurrent") == 0) {
86 deny_delete_current = parse_deny_action(var, value);
87 return 0;
90 if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
91 prefer_ofs_delta = git_config_bool(var, value);
92 return 0;
95 if (strcmp(var, "receive.updateserverinfo") == 0) {
96 auto_update_server_info = git_config_bool(var, value);
97 return 0;
100 if (strcmp(var, "receive.autogc") == 0) {
101 auto_gc = git_config_bool(var, value);
102 return 0;
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 */
137 static const char pre_receive_hook[] = "hooks/pre-receive";
138 static const char post_receive_hook[] = "hooks/post-receive";
140 static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
141 static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
143 static void report_message(const char *prefix, const char *err, va_list params)
145 int sz = strlen(prefix);
146 char msg[4096];
148 strncpy(msg, prefix, sz);
149 sz += vsnprintf(msg + sz, sizeof(msg) - sz, err, params);
150 if (sz > (sizeof(msg) - 1))
151 sz = sizeof(msg) - 1;
152 msg[sz++] = '\n';
154 if (use_sideband)
155 send_sideband(1, 2, msg, sz, use_sideband);
156 else
157 xwrite(2, msg, sz);
160 static void rp_warning(const char *err, ...)
162 va_list params;
163 va_start(params, err);
164 report_message("warning: ", err, params);
165 va_end(params);
168 static void rp_error(const char *err, ...)
170 va_list params;
171 va_start(params, err);
172 report_message("error: ", err, params);
173 va_end(params);
176 static int copy_to_sideband(int in, int out, void *arg)
178 char data[128];
179 while (1) {
180 ssize_t sz = xread(in, data, sizeof(data));
181 if (sz <= 0)
182 break;
183 send_sideband(1, 2, data, sz, use_sideband);
185 close(in);
186 return 0;
189 static int run_receive_hook(struct command *commands, const char *hook_name)
191 static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
192 struct command *cmd;
193 struct child_process proc;
194 struct async muxer;
195 const char *argv[2];
196 int have_input = 0, code;
198 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
199 if (!cmd->error_string)
200 have_input = 1;
203 if (!have_input || access(hook_name, X_OK) < 0)
204 return 0;
206 argv[0] = hook_name;
207 argv[1] = NULL;
209 memset(&proc, 0, sizeof(proc));
210 proc.argv = argv;
211 proc.in = -1;
212 proc.stdout_to_stderr = 1;
214 if (use_sideband) {
215 memset(&muxer, 0, sizeof(muxer));
216 muxer.proc = copy_to_sideband;
217 muxer.in = -1;
218 code = start_async(&muxer);
219 if (code)
220 return code;
221 proc.err = muxer.in;
224 code = start_command(&proc);
225 if (code) {
226 if (use_sideband)
227 finish_async(&muxer);
228 return code;
231 for (cmd = commands; cmd; cmd = cmd->next) {
232 if (!cmd->error_string) {
233 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
234 sha1_to_hex(cmd->old_sha1),
235 sha1_to_hex(cmd->new_sha1),
236 cmd->ref_name);
237 if (write_in_full(proc.in, buf, n) != n)
238 break;
241 close(proc.in);
242 if (use_sideband)
243 finish_async(&muxer);
244 return finish_command(&proc);
247 static int run_update_hook(struct command *cmd)
249 static const char update_hook[] = "hooks/update";
250 const char *argv[5];
251 struct child_process proc;
252 int code;
254 if (access(update_hook, X_OK) < 0)
255 return 0;
257 argv[0] = update_hook;
258 argv[1] = cmd->ref_name;
259 argv[2] = sha1_to_hex(cmd->old_sha1);
260 argv[3] = sha1_to_hex(cmd->new_sha1);
261 argv[4] = NULL;
263 memset(&proc, 0, sizeof(proc));
264 proc.no_stdin = 1;
265 proc.stdout_to_stderr = 1;
266 proc.err = use_sideband ? -1 : 0;
267 proc.argv = argv;
269 code = start_command(&proc);
270 if (code)
271 return code;
272 if (use_sideband)
273 copy_to_sideband(proc.err, -1, NULL);
274 return finish_command(&proc);
277 static int is_ref_checked_out(const char *ref)
279 if (is_bare_repository())
280 return 0;
282 if (!head_name)
283 return 0;
284 return !strcmp(head_name, ref);
287 static char *refuse_unconfigured_deny_msg[] = {
288 "By default, updating the current branch in a non-bare repository",
289 "is denied, because it will make the index and work tree inconsistent",
290 "with what you pushed, and will require 'git reset --hard' to match",
291 "the work tree to HEAD.",
293 "You can set 'receive.denyCurrentBranch' configuration variable to",
294 "'ignore' or 'warn' in the remote repository to allow pushing into",
295 "its current branch; however, this is not recommended unless you",
296 "arranged to update its work tree to match what you pushed in some",
297 "other way.",
299 "To squelch this message and still keep the default behaviour, set",
300 "'receive.denyCurrentBranch' configuration variable to 'refuse'."
303 static void refuse_unconfigured_deny(void)
305 int i;
306 for (i = 0; i < ARRAY_SIZE(refuse_unconfigured_deny_msg); i++)
307 rp_error("%s", refuse_unconfigured_deny_msg[i]);
310 static char *refuse_unconfigured_deny_delete_current_msg[] = {
311 "By default, deleting the current branch is denied, because the next",
312 "'git clone' won't result in any file checked out, causing confusion.",
314 "You can set 'receive.denyDeleteCurrent' configuration variable to",
315 "'warn' or 'ignore' in the remote repository to allow deleting the",
316 "current branch, with or without a warning message.",
318 "To squelch this message, you can set it to 'refuse'."
321 static void refuse_unconfigured_deny_delete_current(void)
323 int i;
324 for (i = 0;
325 i < ARRAY_SIZE(refuse_unconfigured_deny_delete_current_msg);
326 i++)
327 rp_error("%s", refuse_unconfigured_deny_delete_current_msg[i]);
330 static const char *update(struct command *cmd)
332 const char *name = cmd->ref_name;
333 unsigned char *old_sha1 = cmd->old_sha1;
334 unsigned char *new_sha1 = cmd->new_sha1;
335 struct ref_lock *lock;
337 /* only refs/... are allowed */
338 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
339 rp_error("refusing to create funny ref '%s' remotely", name);
340 return "funny refname";
343 if (is_ref_checked_out(name)) {
344 switch (deny_current_branch) {
345 case DENY_IGNORE:
346 break;
347 case DENY_WARN:
348 rp_warning("updating the current branch");
349 break;
350 case DENY_REFUSE:
351 case DENY_UNCONFIGURED:
352 rp_error("refusing to update checked out branch: %s", name);
353 if (deny_current_branch == DENY_UNCONFIGURED)
354 refuse_unconfigured_deny();
355 return "branch is currently checked out";
359 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
360 error("unpack should have generated %s, "
361 "but I can't find it!", sha1_to_hex(new_sha1));
362 return "bad pack";
365 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
366 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
367 rp_error("denying ref deletion for %s", name);
368 return "deletion prohibited";
371 if (!strcmp(name, head_name)) {
372 switch (deny_delete_current) {
373 case DENY_IGNORE:
374 break;
375 case DENY_WARN:
376 rp_warning("deleting the current branch");
377 break;
378 case DENY_REFUSE:
379 case DENY_UNCONFIGURED:
380 if (deny_delete_current == DENY_UNCONFIGURED)
381 refuse_unconfigured_deny_delete_current();
382 rp_error("refusing to delete the current branch: %s", name);
383 return "deletion of the current branch prohibited";
388 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
389 !is_null_sha1(old_sha1) &&
390 !prefixcmp(name, "refs/heads/")) {
391 struct object *old_object, *new_object;
392 struct commit *old_commit, *new_commit;
393 struct commit_list *bases, *ent;
395 old_object = parse_object(old_sha1);
396 new_object = parse_object(new_sha1);
398 if (!old_object || !new_object ||
399 old_object->type != OBJ_COMMIT ||
400 new_object->type != OBJ_COMMIT) {
401 error("bad sha1 objects for %s", name);
402 return "bad ref";
404 old_commit = (struct commit *)old_object;
405 new_commit = (struct commit *)new_object;
406 bases = get_merge_bases(old_commit, new_commit, 1);
407 for (ent = bases; ent; ent = ent->next)
408 if (!hashcmp(old_sha1, ent->item->object.sha1))
409 break;
410 free_commit_list(bases);
411 if (!ent) {
412 rp_error("denying non-fast-forward %s"
413 " (you should pull first)", name);
414 return "non-fast-forward";
417 if (run_update_hook(cmd)) {
418 rp_error("hook declined to update %s", name);
419 return "hook declined";
422 if (is_null_sha1(new_sha1)) {
423 if (!parse_object(old_sha1)) {
424 rp_warning("Allowing deletion of corrupt ref.");
425 old_sha1 = NULL;
427 if (delete_ref(name, old_sha1, 0)) {
428 rp_error("failed to delete %s", name);
429 return "failed to delete";
431 return NULL; /* good */
433 else {
434 lock = lock_any_ref_for_update(name, old_sha1, 0);
435 if (!lock) {
436 rp_error("failed to lock %s", name);
437 return "failed to lock";
439 if (write_ref_sha1(lock, new_sha1, "push")) {
440 return "failed to write"; /* error() already called */
442 return NULL; /* good */
446 static char update_post_hook[] = "hooks/post-update";
448 static void run_update_post_hook(struct command *commands)
450 struct command *cmd;
451 int argc;
452 const char **argv;
453 struct child_process proc;
455 for (argc = 0, cmd = commands; cmd; cmd = cmd->next) {
456 if (cmd->error_string)
457 continue;
458 argc++;
460 if (!argc || access(update_post_hook, X_OK) < 0)
461 return;
462 argv = xmalloc(sizeof(*argv) * (2 + argc));
463 argv[0] = update_post_hook;
465 for (argc = 1, cmd = commands; cmd; cmd = cmd->next) {
466 char *p;
467 if (cmd->error_string)
468 continue;
469 p = xmalloc(strlen(cmd->ref_name) + 1);
470 strcpy(p, cmd->ref_name);
471 argv[argc] = p;
472 argc++;
474 argv[argc] = NULL;
476 memset(&proc, 0, sizeof(proc));
477 proc.no_stdin = 1;
478 proc.stdout_to_stderr = 1;
479 proc.err = use_sideband ? -1 : 0;
480 proc.argv = argv;
482 if (!start_command(&proc)) {
483 if (use_sideband)
484 copy_to_sideband(proc.err, -1, NULL);
485 finish_command(&proc);
489 static void execute_commands(struct command *commands, const char *unpacker_error)
491 struct command *cmd;
492 unsigned char sha1[20];
494 if (unpacker_error) {
495 for (cmd = commands; cmd; cmd = cmd->next)
496 cmd->error_string = "n/a (unpacker error)";
497 return;
500 if (run_receive_hook(commands, pre_receive_hook)) {
501 for (cmd = commands; cmd; cmd = cmd->next)
502 cmd->error_string = "pre-receive hook declined";
503 return;
506 head_name = resolve_ref("HEAD", sha1, 0, NULL);
508 for (cmd = commands; cmd; cmd = cmd->next)
509 cmd->error_string = update(cmd);
512 static struct command *read_head_info(void)
514 struct command *commands = NULL;
515 struct command **p = &commands;
516 for (;;) {
517 static char line[1000];
518 unsigned char old_sha1[20], new_sha1[20];
519 struct command *cmd;
520 char *refname;
521 int len, reflen;
523 len = packet_read_line(0, line, sizeof(line));
524 if (!len)
525 break;
526 if (line[len-1] == '\n')
527 line[--len] = 0;
528 if (len < 83 ||
529 line[40] != ' ' ||
530 line[81] != ' ' ||
531 get_sha1_hex(line, old_sha1) ||
532 get_sha1_hex(line + 41, new_sha1))
533 die("protocol error: expected old/new/ref, got '%s'",
534 line);
536 refname = line + 82;
537 reflen = strlen(refname);
538 if (reflen + 82 < len) {
539 if (strstr(refname + reflen + 1, "report-status"))
540 report_status = 1;
541 if (strstr(refname + reflen + 1, "side-band-64k"))
542 use_sideband = LARGE_PACKET_MAX;
544 cmd = xmalloc(sizeof(struct command) + len - 80);
545 hashcpy(cmd->old_sha1, old_sha1);
546 hashcpy(cmd->new_sha1, new_sha1);
547 memcpy(cmd->ref_name, line + 82, len - 81);
548 cmd->error_string = NULL;
549 cmd->next = NULL;
550 *p = cmd;
551 p = &cmd->next;
553 return commands;
556 static const char *parse_pack_header(struct pack_header *hdr)
558 switch (read_pack_header(0, hdr)) {
559 case PH_ERROR_EOF:
560 return "eof before pack header was fully read";
562 case PH_ERROR_PACK_SIGNATURE:
563 return "protocol error (pack signature mismatch detected)";
565 case PH_ERROR_PROTOCOL:
566 return "protocol error (pack version unsupported)";
568 default:
569 return "unknown error in parse_pack_header";
571 case 0:
572 return NULL;
576 static const char *pack_lockfile;
578 static const char *unpack(void)
580 struct pack_header hdr;
581 const char *hdr_err;
582 char hdr_arg[38];
584 hdr_err = parse_pack_header(&hdr);
585 if (hdr_err)
586 return hdr_err;
587 snprintf(hdr_arg, sizeof(hdr_arg),
588 "--pack_header=%"PRIu32",%"PRIu32,
589 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
591 if (ntohl(hdr.hdr_entries) < unpack_limit) {
592 int code, i = 0;
593 const char *unpacker[4];
594 unpacker[i++] = "unpack-objects";
595 if (receive_fsck_objects)
596 unpacker[i++] = "--strict";
597 unpacker[i++] = hdr_arg;
598 unpacker[i++] = NULL;
599 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
600 if (!code)
601 return NULL;
602 return "unpack-objects abnormal exit";
603 } else {
604 const char *keeper[7];
605 int s, status, i = 0;
606 char keep_arg[256];
607 struct child_process ip;
609 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
610 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
611 strcpy(keep_arg + s, "localhost");
613 keeper[i++] = "index-pack";
614 keeper[i++] = "--stdin";
615 if (receive_fsck_objects)
616 keeper[i++] = "--strict";
617 keeper[i++] = "--fix-thin";
618 keeper[i++] = hdr_arg;
619 keeper[i++] = keep_arg;
620 keeper[i++] = NULL;
621 memset(&ip, 0, sizeof(ip));
622 ip.argv = keeper;
623 ip.out = -1;
624 ip.git_cmd = 1;
625 status = start_command(&ip);
626 if (status) {
627 return "index-pack fork failed";
629 pack_lockfile = index_pack_lockfile(ip.out);
630 close(ip.out);
631 status = finish_command(&ip);
632 if (!status) {
633 reprepare_packed_git();
634 return NULL;
636 return "index-pack abnormal exit";
640 static void report(struct command *commands, const char *unpack_status)
642 struct command *cmd;
643 struct strbuf buf = STRBUF_INIT;
645 packet_buf_write(&buf, "unpack %s\n",
646 unpack_status ? unpack_status : "ok");
647 for (cmd = commands; cmd; cmd = cmd->next) {
648 if (!cmd->error_string)
649 packet_buf_write(&buf, "ok %s\n",
650 cmd->ref_name);
651 else
652 packet_buf_write(&buf, "ng %s %s\n",
653 cmd->ref_name, cmd->error_string);
655 packet_buf_flush(&buf);
657 if (use_sideband)
658 send_sideband(1, 1, buf.buf, buf.len, use_sideband);
659 else
660 safe_write(1, buf.buf, buf.len);
661 strbuf_release(&buf);
664 static int delete_only(struct command *commands)
666 struct command *cmd;
667 for (cmd = commands; cmd; cmd = cmd->next) {
668 if (!is_null_sha1(cmd->new_sha1))
669 return 0;
671 return 1;
674 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
676 char *other;
677 size_t len;
678 struct remote *remote;
679 struct transport *transport;
680 const struct ref *extra;
682 e->name[-1] = '\0';
683 other = xstrdup(make_absolute_path(e->base));
684 e->name[-1] = '/';
685 len = strlen(other);
687 while (other[len-1] == '/')
688 other[--len] = '\0';
689 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
690 return 0;
691 /* Is this a git repository with refs? */
692 memcpy(other + len - 8, "/refs", 6);
693 if (!is_directory(other))
694 return 0;
695 other[len - 8] = '\0';
696 remote = remote_get(other);
697 transport = transport_get(remote, other);
698 for (extra = transport_get_remote_refs(transport);
699 extra;
700 extra = extra->next) {
701 add_extra_ref(".have", extra->old_sha1, 0);
703 transport_disconnect(transport);
704 free(other);
705 return 0;
708 static void add_alternate_refs(void)
710 foreach_alt_odb(add_refs_from_alternate, NULL);
713 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
715 int advertise_refs = 0;
716 int stateless_rpc = 0;
717 int i;
718 char *dir = NULL;
719 struct command *commands;
721 argv++;
722 for (i = 1; i < argc; i++) {
723 const char *arg = *argv++;
725 if (*arg == '-') {
726 if (!strcmp(arg, "--advertise-refs")) {
727 advertise_refs = 1;
728 continue;
730 if (!strcmp(arg, "--stateless-rpc")) {
731 stateless_rpc = 1;
732 continue;
735 usage(receive_pack_usage);
737 if (dir)
738 usage(receive_pack_usage);
739 dir = xstrdup(arg);
741 if (!dir)
742 usage(receive_pack_usage);
744 setup_path();
746 if (!enter_repo(dir, 0))
747 die("'%s' does not appear to be a git repository", dir);
749 if (is_repository_shallow())
750 die("attempt to push into a shallow repository");
752 git_config(receive_pack_config, NULL);
754 if (0 <= transfer_unpack_limit)
755 unpack_limit = transfer_unpack_limit;
756 else if (0 <= receive_unpack_limit)
757 unpack_limit = receive_unpack_limit;
759 if (advertise_refs || !stateless_rpc) {
760 add_alternate_refs();
761 write_head_info();
762 clear_extra_refs();
764 /* EOF */
765 packet_flush(1);
767 if (advertise_refs)
768 return 0;
770 if ((commands = read_head_info()) != NULL) {
771 const char *unpack_status = NULL;
773 if (!delete_only(commands))
774 unpack_status = unpack();
775 execute_commands(commands, unpack_status);
776 if (pack_lockfile)
777 unlink_or_warn(pack_lockfile);
778 if (report_status)
779 report(commands, unpack_status);
780 run_receive_hook(commands, post_receive_hook);
781 run_update_post_hook(commands);
782 if (auto_gc) {
783 const char *argv_gc_auto[] = {
784 "gc", "--auto", "--quiet", NULL,
786 run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
788 if (auto_update_server_info)
789 update_server_info(0);
791 if (use_sideband)
792 packet_flush(1);
793 return 0;