send-pack: avoid deadlock when pack-object dies early
[git/dscho.git] / builtin-receive-pack.c
blobff3f11731d4a10d807241a10e8860275bedab991
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 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;
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;
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.",
218 "You can set 'receive.denyCurrentBranch' configuration variable to",
219 "'refuse' in the remote repository to forbid pushing into its",
220 "current branch."
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.",
226 "To squelch this message, you can set it to 'warn'.",
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'."
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.",
244 "You can set 'receive.denyDeleteCurrent' configuration variable to",
245 "'refuse' in the remote repository to disallow deleting the current",
246 "branch.",
248 "You can set it to 'ignore' to allow such a delete without a warning.",
250 "To make this warning message less loud, you can set it to 'warn'.",
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'."
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";
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";
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";
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";
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";
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";
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";
353 if (run_update_hook(cmd)) {
354 error("hook declined to update %s", name);
355 return "hook declined";
358 if (is_null_sha1(new_sha1)) {
359 if (!parse_object(old_sha1)) {
360 warning ("Allowing deletion of corrupt ref.");
361 old_sha1 = NULL;
363 if (delete_ref(name, old_sha1, 0)) {
364 error("failed to delete %s", name);
365 return "failed to delete";
367 return NULL; /* good */
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";
375 if (write_ref_sha1(lock, new_sha1, "push")) {
376 return "failed to write"; /* error() already called */
378 return NULL; /* good */
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++;
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++;
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;
424 return;
427 if (run_receive_hook(pre_receive_hook)) {
428 while (cmd) {
429 cmd->error_string = "pre-receive hook declined";
430 cmd = cmd->next;
432 return;
435 head_name = resolve_ref("HEAD", sha1, 0, NULL);
437 while (cmd) {
438 cmd->error_string = update(cmd);
439 cmd = cmd->next;
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;
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;
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;
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";
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;
565 return "index-pack abnormal exit";
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);
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;
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);
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;
658 if (!strcmp(arg, "--stateless-rpc")) {
659 stateless_rpc = 1;
660 continue;
663 usage(receive_pack_usage);
665 if (dir)
666 usage(receive_pack_usage);
667 dir = xstrdup(arg);
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);
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,
715 run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
717 if (auto_update_server_info)
718 update_server_info(0);
720 if (use_sideband)
721 packet_flush(1);
722 return 0;