tag.c: Refactor parse_tag_buffer to be saner to program
[git/jrn.git] / builtin-receive-pack.c
bloba5543f9918c3150e1581108b770a4d4c281e812c
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 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 void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
143 static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
145 static void report_message(const char *prefix, const char *err, va_list params)
147 int sz = strlen(prefix);
148 char msg[4096];
150 strncpy(msg, prefix, sz);
151 sz += vsnprintf(msg + sz, sizeof(msg) - sz, err, params);
152 if (sz > (sizeof(msg) - 1))
153 sz = sizeof(msg) - 1;
154 msg[sz++] = '\n';
156 if (use_sideband)
157 send_sideband(1, 2, msg, sz, use_sideband);
158 else
159 xwrite(2, msg, sz);
162 static void rp_warning(const char *err, ...)
164 va_list params;
165 va_start(params, err);
166 report_message("warning: ", err, params);
167 va_end(params);
170 static void rp_error(const char *err, ...)
172 va_list params;
173 va_start(params, err);
174 report_message("error: ", err, params);
175 va_end(params);
178 static int copy_to_sideband(int in, int out, void *arg)
180 char data[128];
181 while (1) {
182 ssize_t sz = xread(in, data, sizeof(data));
183 if (sz <= 0)
184 break;
185 send_sideband(1, 2, data, sz, use_sideband);
187 close(in);
188 return 0;
191 static int run_receive_hook(const char *hook_name)
193 static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
194 struct command *cmd;
195 struct child_process proc;
196 struct async muxer;
197 const char *argv[2];
198 int have_input = 0, code;
200 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
201 if (!cmd->error_string)
202 have_input = 1;
205 if (!have_input || access(hook_name, X_OK) < 0)
206 return 0;
208 argv[0] = hook_name;
209 argv[1] = NULL;
211 memset(&proc, 0, sizeof(proc));
212 proc.argv = argv;
213 proc.in = -1;
214 proc.stdout_to_stderr = 1;
216 if (use_sideband) {
217 memset(&muxer, 0, sizeof(muxer));
218 muxer.proc = copy_to_sideband;
219 muxer.in = -1;
220 code = start_async(&muxer);
221 if (code)
222 return code;
223 proc.err = muxer.in;
226 code = start_command(&proc);
227 if (code) {
228 if (use_sideband)
229 finish_async(&muxer);
230 return code;
233 for (cmd = commands; cmd; cmd = cmd->next) {
234 if (!cmd->error_string) {
235 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
236 sha1_to_hex(cmd->old_sha1),
237 sha1_to_hex(cmd->new_sha1),
238 cmd->ref_name);
239 if (write_in_full(proc.in, buf, n) != n)
240 break;
243 close(proc.in);
244 if (use_sideband)
245 finish_async(&muxer);
246 return finish_command(&proc);
249 static int run_update_hook(struct command *cmd)
251 static const char update_hook[] = "hooks/update";
252 const char *argv[5];
253 struct child_process proc;
254 int code;
256 if (access(update_hook, X_OK) < 0)
257 return 0;
259 argv[0] = update_hook;
260 argv[1] = cmd->ref_name;
261 argv[2] = sha1_to_hex(cmd->old_sha1);
262 argv[3] = sha1_to_hex(cmd->new_sha1);
263 argv[4] = NULL;
265 memset(&proc, 0, sizeof(proc));
266 proc.no_stdin = 1;
267 proc.stdout_to_stderr = 1;
268 proc.err = use_sideband ? -1 : 0;
269 proc.argv = argv;
271 code = start_command(&proc);
272 if (code)
273 return code;
274 if (use_sideband)
275 copy_to_sideband(proc.err, -1, NULL);
276 return finish_command(&proc);
279 static int is_ref_checked_out(const char *ref)
281 if (is_bare_repository())
282 return 0;
284 if (!head_name)
285 return 0;
286 return !strcmp(head_name, ref);
289 static char *warn_unconfigured_deny_msg[] = {
290 "Updating the currently checked out branch may cause confusion,",
291 "as the index and work tree do not reflect changes that are in HEAD.",
292 "As a result, you may see the changes you just pushed into it",
293 "reverted when you run 'git diff' over there, and you may want",
294 "to run 'git reset --hard' before starting to work to recover.",
296 "You can set 'receive.denyCurrentBranch' configuration variable to",
297 "'refuse' in the remote repository to forbid pushing into its",
298 "current branch."
300 "To allow pushing into the current branch, you can set it to 'ignore';",
301 "but this is not recommended unless you arranged to update its work",
302 "tree to match what you pushed in some other way.",
304 "To squelch this message, you can set it to 'warn'.",
306 "Note that the default will change in a future version of git",
307 "to refuse updating the current branch unless you have the",
308 "configuration variable set to either 'ignore' or 'warn'."
311 static void warn_unconfigured_deny(void)
313 int i;
314 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
315 rp_warning("%s", warn_unconfigured_deny_msg[i]);
318 static char *warn_unconfigured_deny_delete_current_msg[] = {
319 "Deleting the current branch can cause confusion by making the next",
320 "'git clone' not check out any file.",
322 "You can set 'receive.denyDeleteCurrent' configuration variable to",
323 "'refuse' in the remote repository to disallow deleting the current",
324 "branch.",
326 "You can set it to 'ignore' to allow such a delete without a warning.",
328 "To make this warning message less loud, you can set it to 'warn'.",
330 "Note that the default will change in a future version of git",
331 "to refuse deleting the current branch unless you have the",
332 "configuration variable set to either 'ignore' or 'warn'."
335 static void warn_unconfigured_deny_delete_current(void)
337 int i;
338 for (i = 0;
339 i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
340 i++)
341 rp_warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
344 static const char *update(struct command *cmd)
346 const char *name = cmd->ref_name;
347 unsigned char *old_sha1 = cmd->old_sha1;
348 unsigned char *new_sha1 = cmd->new_sha1;
349 struct ref_lock *lock;
351 /* only refs/... are allowed */
352 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
353 rp_error("refusing to create funny ref '%s' remotely", name);
354 return "funny refname";
357 if (is_ref_checked_out(name)) {
358 switch (deny_current_branch) {
359 case DENY_IGNORE:
360 break;
361 case DENY_UNCONFIGURED:
362 case DENY_WARN:
363 rp_warning("updating the current branch");
364 if (deny_current_branch == DENY_UNCONFIGURED)
365 warn_unconfigured_deny();
366 break;
367 case DENY_REFUSE:
368 rp_error("refusing to update checked out branch: %s", name);
369 return "branch is currently checked out";
373 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
374 error("unpack should have generated %s, "
375 "but I can't find it!", sha1_to_hex(new_sha1));
376 return "bad pack";
379 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
380 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
381 rp_error("denying ref deletion for %s", name);
382 return "deletion prohibited";
385 if (!strcmp(name, head_name)) {
386 switch (deny_delete_current) {
387 case DENY_IGNORE:
388 break;
389 case DENY_WARN:
390 case DENY_UNCONFIGURED:
391 if (deny_delete_current == DENY_UNCONFIGURED)
392 warn_unconfigured_deny_delete_current();
393 rp_warning("deleting the current branch");
394 break;
395 case DENY_REFUSE:
396 rp_error("refusing to delete the current branch: %s", name);
397 return "deletion of the current branch prohibited";
402 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
403 !is_null_sha1(old_sha1) &&
404 !prefixcmp(name, "refs/heads/")) {
405 struct object *old_object, *new_object;
406 struct commit *old_commit, *new_commit;
407 struct commit_list *bases, *ent;
409 old_object = parse_object(old_sha1);
410 new_object = parse_object(new_sha1);
412 if (!old_object || !new_object ||
413 old_object->type != OBJ_COMMIT ||
414 new_object->type != OBJ_COMMIT) {
415 error("bad sha1 objects for %s", name);
416 return "bad ref";
418 old_commit = (struct commit *)old_object;
419 new_commit = (struct commit *)new_object;
420 bases = get_merge_bases(old_commit, new_commit, 1);
421 for (ent = bases; ent; ent = ent->next)
422 if (!hashcmp(old_sha1, ent->item->object.sha1))
423 break;
424 free_commit_list(bases);
425 if (!ent) {
426 rp_error("denying non-fast-forward %s"
427 " (you should pull first)", name);
428 return "non-fast-forward";
431 if (run_update_hook(cmd)) {
432 rp_error("hook declined to update %s", name);
433 return "hook declined";
436 if (is_null_sha1(new_sha1)) {
437 if (!parse_object(old_sha1)) {
438 rp_warning("Allowing deletion of corrupt ref.");
439 old_sha1 = NULL;
441 if (delete_ref(name, old_sha1, 0)) {
442 rp_error("failed to delete %s", name);
443 return "failed to delete";
445 return NULL; /* good */
447 else {
448 lock = lock_any_ref_for_update(name, old_sha1, 0);
449 if (!lock) {
450 rp_error("failed to lock %s", name);
451 return "failed to lock";
453 if (write_ref_sha1(lock, new_sha1, "push")) {
454 return "failed to write"; /* error() already called */
456 return NULL; /* good */
460 static char update_post_hook[] = "hooks/post-update";
462 static void run_update_post_hook(struct command *cmd)
464 struct command *cmd_p;
465 int argc;
466 const char **argv;
467 struct child_process proc;
469 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
470 if (cmd_p->error_string)
471 continue;
472 argc++;
474 if (!argc || access(update_post_hook, X_OK) < 0)
475 return;
476 argv = xmalloc(sizeof(*argv) * (2 + argc));
477 argv[0] = update_post_hook;
479 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
480 char *p;
481 if (cmd_p->error_string)
482 continue;
483 p = xmalloc(strlen(cmd_p->ref_name) + 1);
484 strcpy(p, cmd_p->ref_name);
485 argv[argc] = p;
486 argc++;
488 argv[argc] = NULL;
490 memset(&proc, 0, sizeof(proc));
491 proc.no_stdin = 1;
492 proc.stdout_to_stderr = 1;
493 proc.err = use_sideband ? -1 : 0;
494 proc.argv = argv;
496 if (!start_command(&proc)) {
497 if (use_sideband)
498 copy_to_sideband(proc.err, -1, NULL);
499 finish_command(&proc);
503 static void execute_commands(const char *unpacker_error)
505 struct command *cmd = commands;
506 unsigned char sha1[20];
508 if (unpacker_error) {
509 while (cmd) {
510 cmd->error_string = "n/a (unpacker error)";
511 cmd = cmd->next;
513 return;
516 if (run_receive_hook(pre_receive_hook)) {
517 while (cmd) {
518 cmd->error_string = "pre-receive hook declined";
519 cmd = cmd->next;
521 return;
524 head_name = resolve_ref("HEAD", sha1, 0, NULL);
526 while (cmd) {
527 cmd->error_string = update(cmd);
528 cmd = cmd->next;
532 static void read_head_info(void)
534 struct command **p = &commands;
535 for (;;) {
536 static char line[1000];
537 unsigned char old_sha1[20], new_sha1[20];
538 struct command *cmd;
539 char *refname;
540 int len, reflen;
542 len = packet_read_line(0, line, sizeof(line));
543 if (!len)
544 break;
545 if (line[len-1] == '\n')
546 line[--len] = 0;
547 if (len < 83 ||
548 line[40] != ' ' ||
549 line[81] != ' ' ||
550 get_sha1_hex(line, old_sha1) ||
551 get_sha1_hex(line + 41, new_sha1))
552 die("protocol error: expected old/new/ref, got '%s'",
553 line);
555 refname = line + 82;
556 reflen = strlen(refname);
557 if (reflen + 82 < len) {
558 if (strstr(refname + reflen + 1, "report-status"))
559 report_status = 1;
560 if (strstr(refname + reflen + 1, "side-band-64k"))
561 use_sideband = LARGE_PACKET_MAX;
563 cmd = xmalloc(sizeof(struct command) + len - 80);
564 hashcpy(cmd->old_sha1, old_sha1);
565 hashcpy(cmd->new_sha1, new_sha1);
566 memcpy(cmd->ref_name, line + 82, len - 81);
567 cmd->error_string = NULL;
568 cmd->next = NULL;
569 *p = cmd;
570 p = &cmd->next;
574 static const char *parse_pack_header(struct pack_header *hdr)
576 switch (read_pack_header(0, hdr)) {
577 case PH_ERROR_EOF:
578 return "eof before pack header was fully read";
580 case PH_ERROR_PACK_SIGNATURE:
581 return "protocol error (pack signature mismatch detected)";
583 case PH_ERROR_PROTOCOL:
584 return "protocol error (pack version unsupported)";
586 default:
587 return "unknown error in parse_pack_header";
589 case 0:
590 return NULL;
594 static const char *pack_lockfile;
596 static const char *unpack(void)
598 struct pack_header hdr;
599 const char *hdr_err;
600 char hdr_arg[38];
602 hdr_err = parse_pack_header(&hdr);
603 if (hdr_err)
604 return hdr_err;
605 snprintf(hdr_arg, sizeof(hdr_arg),
606 "--pack_header=%"PRIu32",%"PRIu32,
607 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
609 if (ntohl(hdr.hdr_entries) < unpack_limit) {
610 int code, i = 0;
611 const char *unpacker[4];
612 unpacker[i++] = "unpack-objects";
613 if (receive_fsck_objects)
614 unpacker[i++] = "--strict";
615 unpacker[i++] = hdr_arg;
616 unpacker[i++] = NULL;
617 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
618 if (!code)
619 return NULL;
620 return "unpack-objects abnormal exit";
621 } else {
622 const char *keeper[7];
623 int s, status, i = 0;
624 char keep_arg[256];
625 struct child_process ip;
627 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
628 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
629 strcpy(keep_arg + s, "localhost");
631 keeper[i++] = "index-pack";
632 keeper[i++] = "--stdin";
633 if (receive_fsck_objects)
634 keeper[i++] = "--strict";
635 keeper[i++] = "--fix-thin";
636 keeper[i++] = hdr_arg;
637 keeper[i++] = keep_arg;
638 keeper[i++] = NULL;
639 memset(&ip, 0, sizeof(ip));
640 ip.argv = keeper;
641 ip.out = -1;
642 ip.git_cmd = 1;
643 status = start_command(&ip);
644 if (status) {
645 return "index-pack fork failed";
647 pack_lockfile = index_pack_lockfile(ip.out);
648 close(ip.out);
649 status = finish_command(&ip);
650 if (!status) {
651 reprepare_packed_git();
652 return NULL;
654 return "index-pack abnormal exit";
658 static void report(const char *unpack_status)
660 struct command *cmd;
661 struct strbuf buf = STRBUF_INIT;
663 packet_buf_write(&buf, "unpack %s\n",
664 unpack_status ? unpack_status : "ok");
665 for (cmd = commands; cmd; cmd = cmd->next) {
666 if (!cmd->error_string)
667 packet_buf_write(&buf, "ok %s\n",
668 cmd->ref_name);
669 else
670 packet_buf_write(&buf, "ng %s %s\n",
671 cmd->ref_name, cmd->error_string);
673 packet_buf_flush(&buf);
675 if (use_sideband)
676 send_sideband(1, 1, buf.buf, buf.len, use_sideband);
677 else
678 safe_write(1, buf.buf, buf.len);
679 strbuf_release(&buf);
682 static int delete_only(struct command *cmd)
684 while (cmd) {
685 if (!is_null_sha1(cmd->new_sha1))
686 return 0;
687 cmd = cmd->next;
689 return 1;
692 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
694 char *other;
695 size_t len;
696 struct remote *remote;
697 struct transport *transport;
698 const struct ref *extra;
700 e->name[-1] = '\0';
701 other = xstrdup(make_absolute_path(e->base));
702 e->name[-1] = '/';
703 len = strlen(other);
705 while (other[len-1] == '/')
706 other[--len] = '\0';
707 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
708 return 0;
709 /* Is this a git repository with refs? */
710 memcpy(other + len - 8, "/refs", 6);
711 if (!is_directory(other))
712 return 0;
713 other[len - 8] = '\0';
714 remote = remote_get(other);
715 transport = transport_get(remote, other);
716 for (extra = transport_get_remote_refs(transport);
717 extra;
718 extra = extra->next) {
719 add_extra_ref(".have", extra->old_sha1, 0);
721 transport_disconnect(transport);
722 free(other);
723 return 0;
726 static void add_alternate_refs(void)
728 foreach_alt_odb(add_refs_from_alternate, NULL);
731 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
733 int advertise_refs = 0;
734 int stateless_rpc = 0;
735 int i;
736 char *dir = NULL;
738 argv++;
739 for (i = 1; i < argc; i++) {
740 const char *arg = *argv++;
742 if (*arg == '-') {
743 if (!strcmp(arg, "--advertise-refs")) {
744 advertise_refs = 1;
745 continue;
747 if (!strcmp(arg, "--stateless-rpc")) {
748 stateless_rpc = 1;
749 continue;
752 usage(receive_pack_usage);
754 if (dir)
755 usage(receive_pack_usage);
756 dir = xstrdup(arg);
758 if (!dir)
759 usage(receive_pack_usage);
761 setup_path();
763 if (!enter_repo(dir, 0))
764 die("'%s' does not appear to be a git repository", dir);
766 if (is_repository_shallow())
767 die("attempt to push into a shallow repository");
769 git_config(receive_pack_config, NULL);
771 if (0 <= transfer_unpack_limit)
772 unpack_limit = transfer_unpack_limit;
773 else if (0 <= receive_unpack_limit)
774 unpack_limit = receive_unpack_limit;
776 if (advertise_refs || !stateless_rpc) {
777 add_alternate_refs();
778 write_head_info();
779 clear_extra_refs();
781 /* EOF */
782 packet_flush(1);
784 if (advertise_refs)
785 return 0;
787 read_head_info();
788 if (commands) {
789 const char *unpack_status = NULL;
791 if (!delete_only(commands))
792 unpack_status = unpack();
793 execute_commands(unpack_status);
794 if (pack_lockfile)
795 unlink_or_warn(pack_lockfile);
796 if (report_status)
797 report(unpack_status);
798 run_receive_hook(post_receive_hook);
799 run_update_post_hook(commands);
800 if (auto_gc) {
801 const char *argv_gc_auto[] = {
802 "gc", "--auto", "--quiet", NULL,
804 run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
806 if (auto_update_server_info)
807 update_server_info(0);
809 if (use_sideband)
810 packet_flush(1);
811 return 0;