Clean up and simplify rev_compare_tree()
[git/dscho.git] / builtin-receive-pack.c
blob0b08da9b595432efa231eb59d88ecd2b422eb56a
1 #include "cache.h"
2 #include "pack.h"
3 #include "refs.h"
4 #include "pkt-line.h"
5 #include "run-command.h"
6 #include "exec_cmd.h"
7 #include "commit.h"
8 #include "object.h"
9 #include "remote.h"
10 #include "transport.h"
12 static const char receive_pack_usage[] = "git receive-pack <git-dir>";
14 enum deny_action {
15 DENY_UNCONFIGURED,
16 DENY_IGNORE,
17 DENY_WARN,
18 DENY_REFUSE,
21 static int deny_deletes;
22 static int deny_non_fast_forwards;
23 static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
24 static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
25 static int receive_fsck_objects;
26 static int receive_unpack_limit = -1;
27 static int transfer_unpack_limit = -1;
28 static int unpack_limit = 100;
29 static int report_status;
30 static int prefer_ofs_delta = 1;
31 static const char *head_name;
32 static char *capabilities_to_send;
34 static enum deny_action parse_deny_action(const char *var, const char *value)
36 if (value) {
37 if (!strcasecmp(value, "ignore"))
38 return DENY_IGNORE;
39 if (!strcasecmp(value, "warn"))
40 return DENY_WARN;
41 if (!strcasecmp(value, "refuse"))
42 return DENY_REFUSE;
44 if (git_config_bool(var, value))
45 return DENY_REFUSE;
46 return DENY_IGNORE;
49 static int receive_pack_config(const char *var, const char *value, void *cb)
51 if (strcmp(var, "receive.denydeletes") == 0) {
52 deny_deletes = git_config_bool(var, value);
53 return 0;
56 if (strcmp(var, "receive.denynonfastforwards") == 0) {
57 deny_non_fast_forwards = git_config_bool(var, value);
58 return 0;
61 if (strcmp(var, "receive.unpacklimit") == 0) {
62 receive_unpack_limit = git_config_int(var, value);
63 return 0;
66 if (strcmp(var, "transfer.unpacklimit") == 0) {
67 transfer_unpack_limit = git_config_int(var, value);
68 return 0;
71 if (strcmp(var, "receive.fsckobjects") == 0) {
72 receive_fsck_objects = git_config_bool(var, value);
73 return 0;
76 if (!strcmp(var, "receive.denycurrentbranch")) {
77 deny_current_branch = parse_deny_action(var, value);
78 return 0;
81 if (strcmp(var, "receive.denydeletecurrent") == 0) {
82 deny_delete_current = parse_deny_action(var, value);
83 return 0;
86 if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
87 prefer_ofs_delta = git_config_bool(var, value);
88 return 0;
91 return git_default_config(var, value, cb);
94 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
96 if (!capabilities_to_send)
97 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
98 else
99 packet_write(1, "%s %s%c%s\n",
100 sha1_to_hex(sha1), path, 0, capabilities_to_send);
101 capabilities_to_send = NULL;
102 return 0;
105 static void write_head_info(void)
107 for_each_ref(show_ref, NULL);
108 if (capabilities_to_send)
109 show_ref("capabilities^{}", null_sha1, 0, NULL);
113 struct command {
114 struct command *next;
115 const char *error_string;
116 unsigned char old_sha1[20];
117 unsigned char new_sha1[20];
118 char ref_name[FLEX_ARRAY]; /* more */
121 static struct command *commands;
123 static const char pre_receive_hook[] = "hooks/pre-receive";
124 static const char post_receive_hook[] = "hooks/post-receive";
126 static int hook_status(int code, const char *hook_name)
128 switch (code) {
129 case 0:
130 return 0;
131 case -ERR_RUN_COMMAND_FORK:
132 return error("hook fork failed");
133 case -ERR_RUN_COMMAND_EXEC:
134 return error("hook execute failed");
135 case -ERR_RUN_COMMAND_PIPE:
136 return error("hook pipe failed");
137 case -ERR_RUN_COMMAND_WAITPID:
138 return error("waitpid failed");
139 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
140 return error("waitpid is confused");
141 case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
142 return error("%s died of signal", hook_name);
143 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
144 return error("%s died strangely", hook_name);
145 default:
146 error("%s exited with error code %d", hook_name, -code);
147 return -code;
151 static int run_receive_hook(const char *hook_name)
153 static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
154 struct command *cmd;
155 struct child_process proc;
156 const char *argv[2];
157 int have_input = 0, code;
159 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
160 if (!cmd->error_string)
161 have_input = 1;
164 if (!have_input || access(hook_name, X_OK) < 0)
165 return 0;
167 argv[0] = hook_name;
168 argv[1] = NULL;
170 memset(&proc, 0, sizeof(proc));
171 proc.argv = argv;
172 proc.in = -1;
173 proc.stdout_to_stderr = 1;
175 code = start_command(&proc);
176 if (code)
177 return hook_status(code, hook_name);
178 for (cmd = commands; cmd; cmd = cmd->next) {
179 if (!cmd->error_string) {
180 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
181 sha1_to_hex(cmd->old_sha1),
182 sha1_to_hex(cmd->new_sha1),
183 cmd->ref_name);
184 if (write_in_full(proc.in, buf, n) != n)
185 break;
188 close(proc.in);
189 return hook_status(finish_command(&proc), hook_name);
192 static int run_update_hook(struct command *cmd)
194 static const char update_hook[] = "hooks/update";
195 struct child_process proc;
196 const char *argv[5];
198 if (access(update_hook, X_OK) < 0)
199 return 0;
201 argv[0] = update_hook;
202 argv[1] = cmd->ref_name;
203 argv[2] = sha1_to_hex(cmd->old_sha1);
204 argv[3] = sha1_to_hex(cmd->new_sha1);
205 argv[4] = NULL;
207 memset(&proc, 0, sizeof(proc));
208 proc.argv = argv;
209 proc.no_stdin = 1;
210 proc.stdout_to_stderr = 1;
212 return hook_status(run_command(&proc), update_hook);
215 static int is_ref_checked_out(const char *ref)
217 if (is_bare_repository())
218 return 0;
220 if (!head_name)
221 return 0;
222 return !strcmp(head_name, ref);
225 static char *warn_unconfigured_deny_msg[] = {
226 "Updating the currently checked out branch may cause confusion,",
227 "as the index and work tree do not reflect changes that are in HEAD.",
228 "As a result, you may see the changes you just pushed into it",
229 "reverted when you run 'git diff' over there, and you may want",
230 "to run 'git reset --hard' before starting to work to recover.",
232 "You can set 'receive.denyCurrentBranch' configuration variable to",
233 "'refuse' in the remote repository to forbid pushing into its",
234 "current branch."
236 "To allow pushing into the current branch, you can set it to 'ignore';",
237 "but this is not recommended unless you arranged to update its work",
238 "tree to match what you pushed in some other way.",
240 "To squelch this message, you can set it to 'warn'.",
242 "Note that the default will change in a future version of git",
243 "to refuse updating the current branch unless you have the",
244 "configuration variable set to either 'ignore' or 'warn'."
247 static void warn_unconfigured_deny(void)
249 int i;
250 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
251 warning("%s", warn_unconfigured_deny_msg[i]);
254 static char *warn_unconfigured_deny_delete_current_msg[] = {
255 "Deleting the current branch can cause confusion by making the next",
256 "'git clone' not check out any file.",
258 "You can set 'receive.denyDeleteCurrent' configuration variable to",
259 "'refuse' in the remote repository to disallow deleting the current",
260 "branch.",
262 "You can set it to 'ignore' to allow such a delete without a warning.",
264 "To make this warning message less loud, you can set it to 'warn'.",
266 "Note that the default will change in a future version of git",
267 "to refuse deleting the current branch unless you have the",
268 "configuration variable set to either 'ignore' or 'warn'."
271 static void warn_unconfigured_deny_delete_current(void)
273 int i;
274 for (i = 0;
275 i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
276 i++)
277 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
280 static const char *update(struct command *cmd)
282 const char *name = cmd->ref_name;
283 unsigned char *old_sha1 = cmd->old_sha1;
284 unsigned char *new_sha1 = cmd->new_sha1;
285 struct ref_lock *lock;
287 /* only refs/... are allowed */
288 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
289 error("refusing to create funny ref '%s' remotely", name);
290 return "funny refname";
293 if (is_ref_checked_out(name)) {
294 switch (deny_current_branch) {
295 case DENY_IGNORE:
296 break;
297 case DENY_UNCONFIGURED:
298 case DENY_WARN:
299 warning("updating the current branch");
300 if (deny_current_branch == DENY_UNCONFIGURED)
301 warn_unconfigured_deny();
302 break;
303 case DENY_REFUSE:
304 error("refusing to update checked out branch: %s", name);
305 return "branch is currently checked out";
309 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
310 error("unpack should have generated %s, "
311 "but I can't find it!", sha1_to_hex(new_sha1));
312 return "bad pack";
315 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
316 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
317 error("denying ref deletion for %s", name);
318 return "deletion prohibited";
321 if (!strcmp(name, head_name)) {
322 switch (deny_delete_current) {
323 case DENY_IGNORE:
324 break;
325 case DENY_WARN:
326 case DENY_UNCONFIGURED:
327 if (deny_delete_current == DENY_UNCONFIGURED)
328 warn_unconfigured_deny_delete_current();
329 warning("deleting the current branch");
330 break;
331 case DENY_REFUSE:
332 error("refusing to delete the current branch: %s", name);
333 return "deletion of the current branch prohibited";
338 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
339 !is_null_sha1(old_sha1) &&
340 !prefixcmp(name, "refs/heads/")) {
341 struct object *old_object, *new_object;
342 struct commit *old_commit, *new_commit;
343 struct commit_list *bases, *ent;
345 old_object = parse_object(old_sha1);
346 new_object = parse_object(new_sha1);
348 if (!old_object || !new_object ||
349 old_object->type != OBJ_COMMIT ||
350 new_object->type != OBJ_COMMIT) {
351 error("bad sha1 objects for %s", name);
352 return "bad ref";
354 old_commit = (struct commit *)old_object;
355 new_commit = (struct commit *)new_object;
356 bases = get_merge_bases(old_commit, new_commit, 1);
357 for (ent = bases; ent; ent = ent->next)
358 if (!hashcmp(old_sha1, ent->item->object.sha1))
359 break;
360 free_commit_list(bases);
361 if (!ent) {
362 error("denying non-fast forward %s"
363 " (you should pull first)", name);
364 return "non-fast forward";
367 if (run_update_hook(cmd)) {
368 error("hook declined to update %s", name);
369 return "hook declined";
372 if (is_null_sha1(new_sha1)) {
373 if (!parse_object(old_sha1)) {
374 warning ("Allowing deletion of corrupt ref.");
375 old_sha1 = NULL;
377 if (delete_ref(name, old_sha1, 0)) {
378 error("failed to delete %s", name);
379 return "failed to delete";
381 return NULL; /* good */
383 else {
384 lock = lock_any_ref_for_update(name, old_sha1, 0);
385 if (!lock) {
386 error("failed to lock %s", name);
387 return "failed to lock";
389 if (write_ref_sha1(lock, new_sha1, "push")) {
390 return "failed to write"; /* error() already called */
392 return NULL; /* good */
396 static char update_post_hook[] = "hooks/post-update";
398 static void run_update_post_hook(struct command *cmd)
400 struct command *cmd_p;
401 int argc;
402 const char **argv;
404 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
405 if (cmd_p->error_string)
406 continue;
407 argc++;
409 if (!argc || access(update_post_hook, X_OK) < 0)
410 return;
411 argv = xmalloc(sizeof(*argv) * (2 + argc));
412 argv[0] = update_post_hook;
414 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
415 char *p;
416 if (cmd_p->error_string)
417 continue;
418 p = xmalloc(strlen(cmd_p->ref_name) + 1);
419 strcpy(p, cmd_p->ref_name);
420 argv[argc] = p;
421 argc++;
423 argv[argc] = NULL;
424 run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
425 | RUN_COMMAND_STDOUT_TO_STDERR);
428 static void execute_commands(const char *unpacker_error)
430 struct command *cmd = commands;
431 unsigned char sha1[20];
433 if (unpacker_error) {
434 while (cmd) {
435 cmd->error_string = "n/a (unpacker error)";
436 cmd = cmd->next;
438 return;
441 if (run_receive_hook(pre_receive_hook)) {
442 while (cmd) {
443 cmd->error_string = "pre-receive hook declined";
444 cmd = cmd->next;
446 return;
449 head_name = resolve_ref("HEAD", sha1, 0, NULL);
451 while (cmd) {
452 cmd->error_string = update(cmd);
453 cmd = cmd->next;
457 static void read_head_info(void)
459 struct command **p = &commands;
460 for (;;) {
461 static char line[1000];
462 unsigned char old_sha1[20], new_sha1[20];
463 struct command *cmd;
464 char *refname;
465 int len, reflen;
467 len = packet_read_line(0, line, sizeof(line));
468 if (!len)
469 break;
470 if (line[len-1] == '\n')
471 line[--len] = 0;
472 if (len < 83 ||
473 line[40] != ' ' ||
474 line[81] != ' ' ||
475 get_sha1_hex(line, old_sha1) ||
476 get_sha1_hex(line + 41, new_sha1))
477 die("protocol error: expected old/new/ref, got '%s'",
478 line);
480 refname = line + 82;
481 reflen = strlen(refname);
482 if (reflen + 82 < len) {
483 if (strstr(refname + reflen + 1, "report-status"))
484 report_status = 1;
486 cmd = xmalloc(sizeof(struct command) + len - 80);
487 hashcpy(cmd->old_sha1, old_sha1);
488 hashcpy(cmd->new_sha1, new_sha1);
489 memcpy(cmd->ref_name, line + 82, len - 81);
490 cmd->error_string = NULL;
491 cmd->next = NULL;
492 *p = cmd;
493 p = &cmd->next;
497 static const char *parse_pack_header(struct pack_header *hdr)
499 switch (read_pack_header(0, hdr)) {
500 case PH_ERROR_EOF:
501 return "eof before pack header was fully read";
503 case PH_ERROR_PACK_SIGNATURE:
504 return "protocol error (pack signature mismatch detected)";
506 case PH_ERROR_PROTOCOL:
507 return "protocol error (pack version unsupported)";
509 default:
510 return "unknown error in parse_pack_header";
512 case 0:
513 return NULL;
517 static const char *pack_lockfile;
519 static const char *unpack(void)
521 struct pack_header hdr;
522 const char *hdr_err;
523 char hdr_arg[38];
525 hdr_err = parse_pack_header(&hdr);
526 if (hdr_err)
527 return hdr_err;
528 snprintf(hdr_arg, sizeof(hdr_arg),
529 "--pack_header=%"PRIu32",%"PRIu32,
530 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
532 if (ntohl(hdr.hdr_entries) < unpack_limit) {
533 int code, i = 0;
534 const char *unpacker[4];
535 unpacker[i++] = "unpack-objects";
536 if (receive_fsck_objects)
537 unpacker[i++] = "--strict";
538 unpacker[i++] = hdr_arg;
539 unpacker[i++] = NULL;
540 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
541 switch (code) {
542 case 0:
543 return NULL;
544 case -ERR_RUN_COMMAND_FORK:
545 return "unpack fork failed";
546 case -ERR_RUN_COMMAND_EXEC:
547 return "unpack execute failed";
548 case -ERR_RUN_COMMAND_WAITPID:
549 return "waitpid failed";
550 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
551 return "waitpid is confused";
552 case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
553 return "unpacker died of signal";
554 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
555 return "unpacker died strangely";
556 default:
557 return "unpacker exited with error code";
559 } else {
560 const char *keeper[7];
561 int s, status, i = 0;
562 char keep_arg[256];
563 struct child_process ip;
565 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
566 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
567 strcpy(keep_arg + s, "localhost");
569 keeper[i++] = "index-pack";
570 keeper[i++] = "--stdin";
571 if (receive_fsck_objects)
572 keeper[i++] = "--strict";
573 keeper[i++] = "--fix-thin";
574 keeper[i++] = hdr_arg;
575 keeper[i++] = keep_arg;
576 keeper[i++] = NULL;
577 memset(&ip, 0, sizeof(ip));
578 ip.argv = keeper;
579 ip.out = -1;
580 ip.git_cmd = 1;
581 if (start_command(&ip))
582 return "index-pack fork failed";
583 pack_lockfile = index_pack_lockfile(ip.out);
584 close(ip.out);
585 status = finish_command(&ip);
586 if (!status) {
587 reprepare_packed_git();
588 return NULL;
590 return "index-pack abnormal exit";
594 static void report(const char *unpack_status)
596 struct command *cmd;
597 packet_write(1, "unpack %s\n",
598 unpack_status ? unpack_status : "ok");
599 for (cmd = commands; cmd; cmd = cmd->next) {
600 if (!cmd->error_string)
601 packet_write(1, "ok %s\n",
602 cmd->ref_name);
603 else
604 packet_write(1, "ng %s %s\n",
605 cmd->ref_name, cmd->error_string);
607 packet_flush(1);
610 static int delete_only(struct command *cmd)
612 while (cmd) {
613 if (!is_null_sha1(cmd->new_sha1))
614 return 0;
615 cmd = cmd->next;
617 return 1;
620 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
622 char *other;
623 size_t len;
624 struct remote *remote;
625 struct transport *transport;
626 const struct ref *extra;
628 e->name[-1] = '\0';
629 other = xstrdup(make_absolute_path(e->base));
630 e->name[-1] = '/';
631 len = strlen(other);
633 while (other[len-1] == '/')
634 other[--len] = '\0';
635 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
636 return 0;
637 /* Is this a git repository with refs? */
638 memcpy(other + len - 8, "/refs", 6);
639 if (!is_directory(other))
640 return 0;
641 other[len - 8] = '\0';
642 remote = remote_get(other);
643 transport = transport_get(remote, other);
644 for (extra = transport_get_remote_refs(transport);
645 extra;
646 extra = extra->next) {
647 add_extra_ref(".have", extra->old_sha1, 0);
649 transport_disconnect(transport);
650 free(other);
651 return 0;
654 static void add_alternate_refs(void)
656 foreach_alt_odb(add_refs_from_alternate, NULL);
659 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
661 int i;
662 char *dir = NULL;
664 argv++;
665 for (i = 1; i < argc; i++) {
666 const char *arg = *argv++;
668 if (*arg == '-') {
669 /* Do flag handling here */
670 usage(receive_pack_usage);
672 if (dir)
673 usage(receive_pack_usage);
674 dir = xstrdup(arg);
676 if (!dir)
677 usage(receive_pack_usage);
679 setup_path();
681 if (!enter_repo(dir, 0))
682 die("'%s' does not appear to be a git repository", dir);
684 if (is_repository_shallow())
685 die("attempt to push into a shallow repository");
687 git_config(receive_pack_config, NULL);
689 if (0 <= transfer_unpack_limit)
690 unpack_limit = transfer_unpack_limit;
691 else if (0 <= receive_unpack_limit)
692 unpack_limit = receive_unpack_limit;
694 capabilities_to_send = (prefer_ofs_delta) ?
695 " report-status delete-refs ofs-delta " :
696 " report-status delete-refs ";
698 add_alternate_refs();
699 write_head_info();
700 clear_extra_refs();
702 /* EOF */
703 packet_flush(1);
705 read_head_info();
706 if (commands) {
707 const char *unpack_status = NULL;
709 if (!delete_only(commands))
710 unpack_status = unpack();
711 execute_commands(unpack_status);
712 if (pack_lockfile)
713 unlink_or_warn(pack_lockfile);
714 if (report_status)
715 report(unpack_status);
716 run_receive_hook(post_receive_hook);
717 run_update_post_hook(commands);
719 return 0;