fixup.cc5711424b7ae36276a40c06ede5d95f87ca20f0
[git/dscho.git] / builtin-receive-pack.c
bloba7c2774d7f2b6fa28668365a8c612496fbe65744
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,
19 DENY_UPDATE_INSTEAD,
20 DENY_DETACH_INSTEAD,
23 static int deny_deletes;
24 static int deny_non_fast_forwards;
25 static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
26 static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
27 static int receive_fsck_objects;
28 static int receive_unpack_limit = -1;
29 static int transfer_unpack_limit = -1;
30 static int unpack_limit = 100;
31 static int report_status;
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 char *capabilities_to_send;
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 if (value && !strcasecmp(value, "updateinstead"))
82 deny_current_branch = DENY_UPDATE_INSTEAD;
83 else if (value && !strcasecmp(value, "detachinstead"))
84 deny_current_branch = DENY_DETACH_INSTEAD;
85 else
86 deny_current_branch = parse_deny_action(var, value);
87 return 0;
90 if (strcmp(var, "receive.denydeletecurrent") == 0) {
91 deny_delete_current = parse_deny_action(var, value);
92 return 0;
95 if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
96 prefer_ofs_delta = git_config_bool(var, value);
97 return 0;
100 if (strcmp(var, "receive.updateserverinfo") == 0) {
101 auto_update_server_info = git_config_bool(var, value);
102 return 0;
105 if (strcmp(var, "receive.autogc") == 0) {
106 auto_gc = git_config_bool(var, value);
107 return 0;
110 return git_default_config(var, value, cb);
113 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
115 if (!capabilities_to_send)
116 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
117 else
118 packet_write(1, "%s %s%c%s\n",
119 sha1_to_hex(sha1), path, 0, capabilities_to_send);
120 capabilities_to_send = NULL;
121 return 0;
124 static void write_head_info(void)
126 for_each_ref(show_ref, NULL);
127 if (capabilities_to_send)
128 show_ref("capabilities^{}", null_sha1, 0, NULL);
132 struct command {
133 struct command *next;
134 const char *error_string;
135 unsigned char old_sha1[20];
136 unsigned char new_sha1[20];
137 char ref_name[FLEX_ARRAY]; /* more */
140 static struct command *commands;
142 static const char pre_receive_hook[] = "hooks/pre-receive";
143 static const char post_receive_hook[] = "hooks/post-receive";
145 static int run_receive_hook(const char *hook_name)
147 static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
148 struct command *cmd;
149 struct child_process proc;
150 const char *argv[2];
151 int have_input = 0, code;
153 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
154 if (!cmd->error_string)
155 have_input = 1;
158 if (!have_input || access(hook_name, X_OK) < 0)
159 return 0;
161 argv[0] = hook_name;
162 argv[1] = NULL;
164 memset(&proc, 0, sizeof(proc));
165 proc.argv = argv;
166 proc.in = -1;
167 proc.stdout_to_stderr = 1;
169 code = start_command(&proc);
170 if (code)
171 return code;
172 for (cmd = commands; cmd; cmd = cmd->next) {
173 if (!cmd->error_string) {
174 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
175 sha1_to_hex(cmd->old_sha1),
176 sha1_to_hex(cmd->new_sha1),
177 cmd->ref_name);
178 if (write_in_full(proc.in, buf, n) != n)
179 break;
182 close(proc.in);
183 return finish_command(&proc);
186 static int run_update_hook(struct command *cmd)
188 static const char update_hook[] = "hooks/update";
189 const char *argv[5];
191 if (access(update_hook, X_OK) < 0)
192 return 0;
194 argv[0] = update_hook;
195 argv[1] = cmd->ref_name;
196 argv[2] = sha1_to_hex(cmd->old_sha1);
197 argv[3] = sha1_to_hex(cmd->new_sha1);
198 argv[4] = NULL;
200 return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
201 RUN_COMMAND_STDOUT_TO_STDERR);
204 static int is_ref_checked_out(const char *ref)
206 if (is_bare_repository())
207 return 0;
209 if (!head_name)
210 return 0;
211 return !strcmp(head_name, ref);
214 static char *refuse_unconfigured_deny_msg[] = {
215 "By default, updating the current branch in a non-bare repository",
216 "is denied, because it will make the index and work tree inconsistent",
217 "with what you pushed, and will require 'git reset --hard' to match",
218 "the work tree to HEAD.",
220 "You can set 'receive.denyCurrentBranch' configuration variable to",
221 "'ignore' or 'warn' in the remote repository to allow pushing into",
222 "its current branch; however, this is not recommended unless you",
223 "arranged to update its work tree to match what you pushed in some",
224 "other way.",
226 "To squelch this message and still keep the default behaviour, set",
227 "'receive.denyCurrentBranch' configuration variable to 'refuse'."
230 static void refuse_unconfigured_deny(void)
232 int i;
233 for (i = 0; i < ARRAY_SIZE(refuse_unconfigured_deny_msg); i++)
234 error("%s", refuse_unconfigured_deny_msg[i]);
237 static char *refuse_unconfigured_deny_delete_current_msg[] = {
238 "By default, deleting the current branch is denied, because the next",
239 "'git clone' won't result in any file checked out, causing confusion.",
241 "You can set 'receive.denyDeleteCurrent' configuration variable to",
242 "'warn' or 'ignore' in the remote repository to allow deleting the",
243 "current branch, with or without a warning message.",
245 "To squelch this message, you can set it to 'refuse'."
248 static void refuse_unconfigured_deny_delete_current(void)
250 int i;
251 for (i = 0;
252 i < ARRAY_SIZE(refuse_unconfigured_deny_delete_current_msg);
253 i++)
254 error("%s", refuse_unconfigured_deny_delete_current_msg[i]);
257 static void merge_worktree(unsigned char *sha1)
259 const char *update_refresh[] = {
260 "update-index", "--refresh", NULL
262 const char *read_tree[] = {
263 "read-tree", "-u", "-m", sha1_to_hex(sha1), NULL
265 struct child_process child;
266 struct strbuf git_env = STRBUF_INIT;
267 const char *env[2];
269 if (is_bare_repository())
270 die ("denyCurrentBranch = updateInstead needs a worktree");
272 strbuf_addf(&git_env, "GIT_DIR=%s", make_absolute_path(get_git_dir()));
273 env[0] = git_env.buf;
274 env[1] = NULL;
276 memset(&child, 0, sizeof(child));
277 child.argv = update_refresh;
278 child.env = env;
279 child.dir = git_work_tree_cfg ? git_work_tree_cfg : "..";
280 child.stdout_to_stderr = 1;
281 child.git_cmd = 1;
282 if (run_command(&child))
283 die ("Could not refresh the index");
285 child.argv = read_tree;
286 child.no_stdin = 1;
287 child.no_stdout = 1;
288 child.stdout_to_stderr = 0;
289 if (run_command(&child))
290 die ("Could not merge working tree with new HEAD. Good luck.");
292 strbuf_release(&git_env);
295 static const char *update(struct command *cmd)
297 const char *name = cmd->ref_name;
298 unsigned char *old_sha1 = cmd->old_sha1;
299 unsigned char *new_sha1 = cmd->new_sha1;
300 struct ref_lock *lock;
302 /* only refs/... are allowed */
303 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
304 error("refusing to create funny ref '%s' remotely", name);
305 return "funny refname";
308 if (is_ref_checked_out(name)) {
309 switch (deny_current_branch) {
310 case DENY_IGNORE:
311 break;
312 case DENY_WARN:
313 warning("updating the current branch");
314 break;
315 case DENY_REFUSE:
316 case DENY_UNCONFIGURED:
317 error("refusing to update checked out branch: %s", name);
318 if (deny_current_branch == DENY_UNCONFIGURED)
319 refuse_unconfigured_deny();
320 return "branch is currently checked out";
321 case DENY_UPDATE_INSTEAD:
322 merge_worktree(new_sha1);
323 break;
324 case DENY_DETACH_INSTEAD:
325 update_ref("push into current branch (detach)", "HEAD",
326 old_sha1, NULL, REF_NODEREF, DIE_ON_ERR);
327 break;
331 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
332 error("unpack should have generated %s, "
333 "but I can't find it!", sha1_to_hex(new_sha1));
334 return "bad pack";
337 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
338 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
339 error("denying ref deletion for %s", name);
340 return "deletion prohibited";
343 if (!strcmp(name, head_name)) {
344 switch (deny_delete_current) {
345 case DENY_IGNORE:
346 break;
347 case DENY_WARN:
348 warning("deleting the current branch");
349 break;
350 case DENY_REFUSE:
351 case DENY_UNCONFIGURED:
352 if (deny_delete_current == DENY_UNCONFIGURED)
353 refuse_unconfigured_deny_delete_current();
354 error("refusing to delete the current branch: %s", name);
355 return "deletion of the current branch prohibited";
356 default:
357 die ("Invalid denyDeleteCurrent setting");
362 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
363 !is_null_sha1(old_sha1) &&
364 !prefixcmp(name, "refs/heads/")) {
365 struct object *old_object, *new_object;
366 struct commit *old_commit, *new_commit;
367 struct commit_list *bases, *ent;
369 old_object = parse_object(old_sha1);
370 new_object = parse_object(new_sha1);
372 if (!old_object || !new_object ||
373 old_object->type != OBJ_COMMIT ||
374 new_object->type != OBJ_COMMIT) {
375 error("bad sha1 objects for %s", name);
376 return "bad ref";
378 old_commit = (struct commit *)old_object;
379 new_commit = (struct commit *)new_object;
380 bases = get_merge_bases(old_commit, new_commit, 1);
381 for (ent = bases; ent; ent = ent->next)
382 if (!hashcmp(old_sha1, ent->item->object.sha1))
383 break;
384 free_commit_list(bases);
385 if (!ent) {
386 error("denying non-fast-forward %s"
387 " (you should pull first)", name);
388 return "non-fast-forward";
391 if (run_update_hook(cmd)) {
392 error("hook declined to update %s", name);
393 return "hook declined";
396 if (is_null_sha1(new_sha1)) {
397 if (!parse_object(old_sha1)) {
398 warning ("Allowing deletion of corrupt ref.");
399 old_sha1 = NULL;
401 if (delete_ref(name, old_sha1, 0)) {
402 error("failed to delete %s", name);
403 return "failed to delete";
405 return NULL; /* good */
407 else {
408 lock = lock_any_ref_for_update(name, old_sha1, 0);
409 if (!lock) {
410 error("failed to lock %s", name);
411 return "failed to lock";
413 if (write_ref_sha1(lock, new_sha1, "push")) {
414 return "failed to write"; /* error() already called */
416 return NULL; /* good */
420 static char update_post_hook[] = "hooks/post-update";
422 static void run_update_post_hook(struct command *cmd)
424 struct command *cmd_p;
425 int argc, status;
426 const char **argv;
428 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
429 if (cmd_p->error_string)
430 continue;
431 argc++;
433 if (!argc || access(update_post_hook, X_OK) < 0)
434 return;
435 argv = xmalloc(sizeof(*argv) * (2 + argc));
436 argv[0] = update_post_hook;
438 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
439 char *p;
440 if (cmd_p->error_string)
441 continue;
442 p = xmalloc(strlen(cmd_p->ref_name) + 1);
443 strcpy(p, cmd_p->ref_name);
444 argv[argc] = p;
445 argc++;
447 argv[argc] = NULL;
448 status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
449 | RUN_COMMAND_STDOUT_TO_STDERR);
452 static void execute_commands(const char *unpacker_error)
454 struct command *cmd = commands;
455 unsigned char sha1[20];
457 if (unpacker_error) {
458 while (cmd) {
459 cmd->error_string = "n/a (unpacker error)";
460 cmd = cmd->next;
462 return;
465 if (run_receive_hook(pre_receive_hook)) {
466 while (cmd) {
467 cmd->error_string = "pre-receive hook declined";
468 cmd = cmd->next;
470 return;
473 head_name = resolve_ref("HEAD", sha1, 0, NULL);
475 while (cmd) {
476 cmd->error_string = update(cmd);
477 cmd = cmd->next;
481 static void read_head_info(void)
483 struct command **p = &commands;
484 for (;;) {
485 static char line[1000];
486 unsigned char old_sha1[20], new_sha1[20];
487 struct command *cmd;
488 char *refname;
489 int len, reflen;
491 len = packet_read_line(0, line, sizeof(line));
492 if (!len)
493 break;
494 if (line[len-1] == '\n')
495 line[--len] = 0;
496 if (len < 83 ||
497 line[40] != ' ' ||
498 line[81] != ' ' ||
499 get_sha1_hex(line, old_sha1) ||
500 get_sha1_hex(line + 41, new_sha1))
501 die("protocol error: expected old/new/ref, got '%s'",
502 line);
504 refname = line + 82;
505 reflen = strlen(refname);
506 if (reflen + 82 < len) {
507 if (strstr(refname + reflen + 1, "report-status"))
508 report_status = 1;
510 cmd = xmalloc(sizeof(struct command) + len - 80);
511 hashcpy(cmd->old_sha1, old_sha1);
512 hashcpy(cmd->new_sha1, new_sha1);
513 memcpy(cmd->ref_name, line + 82, len - 81);
514 cmd->error_string = NULL;
515 cmd->next = NULL;
516 *p = cmd;
517 p = &cmd->next;
521 static const char *parse_pack_header(struct pack_header *hdr)
523 switch (read_pack_header(0, hdr)) {
524 case PH_ERROR_EOF:
525 return "eof before pack header was fully read";
527 case PH_ERROR_PACK_SIGNATURE:
528 return "protocol error (pack signature mismatch detected)";
530 case PH_ERROR_PROTOCOL:
531 return "protocol error (pack version unsupported)";
533 default:
534 return "unknown error in parse_pack_header";
536 case 0:
537 return NULL;
541 static const char *pack_lockfile;
543 static const char *unpack(void)
545 struct pack_header hdr;
546 const char *hdr_err;
547 char hdr_arg[38];
549 hdr_err = parse_pack_header(&hdr);
550 if (hdr_err)
551 return hdr_err;
552 snprintf(hdr_arg, sizeof(hdr_arg),
553 "--pack_header=%"PRIu32",%"PRIu32,
554 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
556 if (ntohl(hdr.hdr_entries) < unpack_limit) {
557 int code, i = 0;
558 const char *unpacker[4];
559 unpacker[i++] = "unpack-objects";
560 if (receive_fsck_objects)
561 unpacker[i++] = "--strict";
562 unpacker[i++] = hdr_arg;
563 unpacker[i++] = NULL;
564 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
565 if (!code)
566 return NULL;
567 return "unpack-objects abnormal exit";
568 } else {
569 const char *keeper[7];
570 int s, status, i = 0;
571 char keep_arg[256];
572 struct child_process ip;
574 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
575 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
576 strcpy(keep_arg + s, "localhost");
578 keeper[i++] = "index-pack";
579 keeper[i++] = "--stdin";
580 if (receive_fsck_objects)
581 keeper[i++] = "--strict";
582 keeper[i++] = "--fix-thin";
583 keeper[i++] = hdr_arg;
584 keeper[i++] = keep_arg;
585 keeper[i++] = NULL;
586 memset(&ip, 0, sizeof(ip));
587 ip.argv = keeper;
588 ip.out = -1;
589 ip.git_cmd = 1;
590 status = start_command(&ip);
591 if (status) {
592 return "index-pack fork failed";
594 pack_lockfile = index_pack_lockfile(ip.out);
595 close(ip.out);
596 status = finish_command(&ip);
597 if (!status) {
598 reprepare_packed_git();
599 return NULL;
601 return "index-pack abnormal exit";
605 static void report(const char *unpack_status)
607 struct command *cmd;
608 packet_write(1, "unpack %s\n",
609 unpack_status ? unpack_status : "ok");
610 for (cmd = commands; cmd; cmd = cmd->next) {
611 if (!cmd->error_string)
612 packet_write(1, "ok %s\n",
613 cmd->ref_name);
614 else
615 packet_write(1, "ng %s %s\n",
616 cmd->ref_name, cmd->error_string);
618 packet_flush(1);
621 static int delete_only(struct command *cmd)
623 while (cmd) {
624 if (!is_null_sha1(cmd->new_sha1))
625 return 0;
626 cmd = cmd->next;
628 return 1;
631 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
633 char *other;
634 size_t len;
635 struct remote *remote;
636 struct transport *transport;
637 const struct ref *extra;
639 e->name[-1] = '\0';
640 other = xstrdup(make_absolute_path(e->base));
641 e->name[-1] = '/';
642 len = strlen(other);
644 while (other[len-1] == '/')
645 other[--len] = '\0';
646 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
647 return 0;
648 /* Is this a git repository with refs? */
649 memcpy(other + len - 8, "/refs", 6);
650 if (!is_directory(other))
651 return 0;
652 other[len - 8] = '\0';
653 remote = remote_get(other);
654 transport = transport_get(remote, other);
655 for (extra = transport_get_remote_refs(transport);
656 extra;
657 extra = extra->next) {
658 add_extra_ref(".have", extra->old_sha1, 0);
660 transport_disconnect(transport);
661 free(other);
662 return 0;
665 static void add_alternate_refs(void)
667 foreach_alt_odb(add_refs_from_alternate, NULL);
670 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
672 int advertise_refs = 0;
673 int stateless_rpc = 0;
674 int i;
675 char *dir = NULL;
677 argv++;
678 for (i = 1; i < argc; i++) {
679 const char *arg = *argv++;
681 if (*arg == '-') {
682 if (!strcmp(arg, "--advertise-refs")) {
683 advertise_refs = 1;
684 continue;
686 if (!strcmp(arg, "--stateless-rpc")) {
687 stateless_rpc = 1;
688 continue;
691 usage(receive_pack_usage);
693 if (dir)
694 usage(receive_pack_usage);
695 dir = xstrdup(arg);
697 if (!dir)
698 usage(receive_pack_usage);
700 setup_path();
702 if (!enter_repo(dir, 0))
703 die("'%s' does not appear to be a git repository", dir);
705 if (is_repository_shallow())
706 die("attempt to push into a shallow repository");
708 git_config(receive_pack_config, NULL);
710 if (0 <= transfer_unpack_limit)
711 unpack_limit = transfer_unpack_limit;
712 else if (0 <= receive_unpack_limit)
713 unpack_limit = receive_unpack_limit;
715 capabilities_to_send = (prefer_ofs_delta) ?
716 " report-status delete-refs ofs-delta " :
717 " report-status delete-refs ";
719 if (advertise_refs || !stateless_rpc) {
720 add_alternate_refs();
721 write_head_info();
722 clear_extra_refs();
724 /* EOF */
725 packet_flush(1);
727 if (advertise_refs)
728 return 0;
730 read_head_info();
731 if (commands) {
732 const char *unpack_status = NULL;
734 if (!delete_only(commands))
735 unpack_status = unpack();
736 execute_commands(unpack_status);
737 if (pack_lockfile)
738 unlink_or_warn(pack_lockfile);
739 if (report_status)
740 report(unpack_status);
741 run_receive_hook(post_receive_hook);
742 run_update_post_hook(commands);
743 if (auto_gc) {
744 const char *argv_gc_auto[] = {
745 "gc", "--auto", "--quiet", NULL,
747 run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
749 if (auto_update_server_info)
750 update_server_info(0);
752 return 0;