Refuse deleting the current branch via push
[git/dscho.git] / builtin-receive-pack.c
blobdb12b813acbe9bade2b854b3a94fed13f6210499
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 run_status(int code, const char *cmd_name)
128 switch (code) {
129 case 0:
130 return 0;
131 case -ERR_RUN_COMMAND_FORK:
132 return error("fork of %s failed", cmd_name);
133 case -ERR_RUN_COMMAND_EXEC:
134 return error("execute of %s failed", cmd_name);
135 case -ERR_RUN_COMMAND_PIPE:
136 return error("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", cmd_name);
143 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
144 return error("%s died strangely", cmd_name);
145 default:
146 error("%s exited with error code %d", cmd_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 run_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 run_status(finish_command(&proc), hook_name);
192 static int run_update_hook(struct command *cmd)
194 static const char update_hook[] = "hooks/update";
195 const char *argv[5];
197 if (access(update_hook, X_OK) < 0)
198 return 0;
200 argv[0] = update_hook;
201 argv[1] = cmd->ref_name;
202 argv[2] = sha1_to_hex(cmd->old_sha1);
203 argv[3] = sha1_to_hex(cmd->new_sha1);
204 argv[4] = NULL;
206 return run_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
207 RUN_COMMAND_STDOUT_TO_STDERR),
208 update_hook);
211 static int is_ref_checked_out(const char *ref)
213 if (is_bare_repository())
214 return 0;
216 if (!head_name)
217 return 0;
218 return !strcmp(head_name, ref);
221 static char *refuse_unconfigured_deny_msg[] = {
222 "By default, updating the current branch in a non-bare repository",
223 "is denied, because it will make the index and work tree inconsistent",
224 "with what you pushed, and will require 'git reset --hard' to match",
225 "the work tree to HEAD.",
227 "You can set 'receive.denyCurrentBranch' configuration variable to",
228 "'ignore' or 'warn' in the remote repository to allow pushing into",
229 "its current branch; however, this is not recommended unless you",
230 "arranged to update its work tree to match what you pushed in some",
231 "other way.",
233 "To squelch this message and still keep the default behaviour, set",
234 "'receive.denyCurrentBranch' configuration variable to 'refuse'."
237 static void refuse_unconfigured_deny(void)
239 int i;
240 for (i = 0; i < ARRAY_SIZE(refuse_unconfigured_deny_msg); i++)
241 error("%s", refuse_unconfigured_deny_msg[i]);
244 static char *refuse_unconfigured_deny_delete_current_msg[] = {
245 "By default, deleting the current branch is denied, because the next",
246 "'git clone' won't result in any file checked out, causing confusion.",
248 "You can set 'receive.denyDeleteCurrent' configuration variable to",
249 "'warn' or 'ignore' in the remote repository to allow deleting the",
250 "current branch, with or without a warning message.",
252 "To squelch this message, you can set it to 'refuse'."
255 static void refuse_unconfigured_deny_delete_current(void)
257 int i;
258 for (i = 0;
259 i < ARRAY_SIZE(refuse_unconfigured_deny_delete_current_msg);
260 i++)
261 error("%s", refuse_unconfigured_deny_delete_current_msg[i]);
264 static const char *update(struct command *cmd)
266 const char *name = cmd->ref_name;
267 unsigned char *old_sha1 = cmd->old_sha1;
268 unsigned char *new_sha1 = cmd->new_sha1;
269 struct ref_lock *lock;
271 /* only refs/... are allowed */
272 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
273 error("refusing to create funny ref '%s' remotely", name);
274 return "funny refname";
277 if (is_ref_checked_out(name)) {
278 switch (deny_current_branch) {
279 case DENY_IGNORE:
280 break;
281 case DENY_WARN:
282 warning("updating the current branch");
283 break;
284 case DENY_REFUSE:
285 case DENY_UNCONFIGURED:
286 error("refusing to update checked out branch: %s", name);
287 if (deny_current_branch == DENY_UNCONFIGURED)
288 refuse_unconfigured_deny();
289 return "branch is currently checked out";
293 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
294 error("unpack should have generated %s, "
295 "but I can't find it!", sha1_to_hex(new_sha1));
296 return "bad pack";
299 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
300 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
301 error("denying ref deletion for %s", name);
302 return "deletion prohibited";
305 if (!strcmp(name, head_name)) {
306 switch (deny_delete_current) {
307 case DENY_IGNORE:
308 break;
309 case DENY_WARN:
310 warning("deleting the current branch");
311 break;
312 case DENY_REFUSE:
313 case DENY_UNCONFIGURED:
314 if (deny_delete_current == DENY_UNCONFIGURED)
315 refuse_unconfigured_deny_delete_current();
316 error("refusing to delete the current branch: %s", name);
317 return "deletion of the current branch prohibited";
322 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
323 !is_null_sha1(old_sha1) &&
324 !prefixcmp(name, "refs/heads/")) {
325 struct object *old_object, *new_object;
326 struct commit *old_commit, *new_commit;
327 struct commit_list *bases, *ent;
329 old_object = parse_object(old_sha1);
330 new_object = parse_object(new_sha1);
332 if (!old_object || !new_object ||
333 old_object->type != OBJ_COMMIT ||
334 new_object->type != OBJ_COMMIT) {
335 error("bad sha1 objects for %s", name);
336 return "bad ref";
338 old_commit = (struct commit *)old_object;
339 new_commit = (struct commit *)new_object;
340 bases = get_merge_bases(old_commit, new_commit, 1);
341 for (ent = bases; ent; ent = ent->next)
342 if (!hashcmp(old_sha1, ent->item->object.sha1))
343 break;
344 free_commit_list(bases);
345 if (!ent) {
346 error("denying non-fast forward %s"
347 " (you should pull first)", name);
348 return "non-fast forward";
351 if (run_update_hook(cmd)) {
352 error("hook declined to update %s", name);
353 return "hook declined";
356 if (is_null_sha1(new_sha1)) {
357 if (!parse_object(old_sha1)) {
358 warning ("Allowing deletion of corrupt ref.");
359 old_sha1 = NULL;
361 if (delete_ref(name, old_sha1, 0)) {
362 error("failed to delete %s", name);
363 return "failed to delete";
365 return NULL; /* good */
367 else {
368 lock = lock_any_ref_for_update(name, old_sha1, 0);
369 if (!lock) {
370 error("failed to lock %s", name);
371 return "failed to lock";
373 if (write_ref_sha1(lock, new_sha1, "push")) {
374 return "failed to write"; /* error() already called */
376 return NULL; /* good */
380 static char update_post_hook[] = "hooks/post-update";
382 static void run_update_post_hook(struct command *cmd)
384 struct command *cmd_p;
385 int argc, status;
386 const char **argv;
388 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
389 if (cmd_p->error_string)
390 continue;
391 argc++;
393 if (!argc || access(update_post_hook, X_OK) < 0)
394 return;
395 argv = xmalloc(sizeof(*argv) * (2 + argc));
396 argv[0] = update_post_hook;
398 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
399 char *p;
400 if (cmd_p->error_string)
401 continue;
402 p = xmalloc(strlen(cmd_p->ref_name) + 1);
403 strcpy(p, cmd_p->ref_name);
404 argv[argc] = p;
405 argc++;
407 argv[argc] = NULL;
408 status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
409 | RUN_COMMAND_STDOUT_TO_STDERR);
410 run_status(status, update_post_hook);
413 static void execute_commands(const char *unpacker_error)
415 struct command *cmd = commands;
416 unsigned char sha1[20];
418 if (unpacker_error) {
419 while (cmd) {
420 cmd->error_string = "n/a (unpacker error)";
421 cmd = cmd->next;
423 return;
426 if (run_receive_hook(pre_receive_hook)) {
427 while (cmd) {
428 cmd->error_string = "pre-receive hook declined";
429 cmd = cmd->next;
431 return;
434 head_name = resolve_ref("HEAD", sha1, 0, NULL);
436 while (cmd) {
437 cmd->error_string = update(cmd);
438 cmd = cmd->next;
442 static void read_head_info(void)
444 struct command **p = &commands;
445 for (;;) {
446 static char line[1000];
447 unsigned char old_sha1[20], new_sha1[20];
448 struct command *cmd;
449 char *refname;
450 int len, reflen;
452 len = packet_read_line(0, line, sizeof(line));
453 if (!len)
454 break;
455 if (line[len-1] == '\n')
456 line[--len] = 0;
457 if (len < 83 ||
458 line[40] != ' ' ||
459 line[81] != ' ' ||
460 get_sha1_hex(line, old_sha1) ||
461 get_sha1_hex(line + 41, new_sha1))
462 die("protocol error: expected old/new/ref, got '%s'",
463 line);
465 refname = line + 82;
466 reflen = strlen(refname);
467 if (reflen + 82 < len) {
468 if (strstr(refname + reflen + 1, "report-status"))
469 report_status = 1;
471 cmd = xmalloc(sizeof(struct command) + len - 80);
472 hashcpy(cmd->old_sha1, old_sha1);
473 hashcpy(cmd->new_sha1, new_sha1);
474 memcpy(cmd->ref_name, line + 82, len - 81);
475 cmd->error_string = NULL;
476 cmd->next = NULL;
477 *p = cmd;
478 p = &cmd->next;
482 static const char *parse_pack_header(struct pack_header *hdr)
484 switch (read_pack_header(0, hdr)) {
485 case PH_ERROR_EOF:
486 return "eof before pack header was fully read";
488 case PH_ERROR_PACK_SIGNATURE:
489 return "protocol error (pack signature mismatch detected)";
491 case PH_ERROR_PROTOCOL:
492 return "protocol error (pack version unsupported)";
494 default:
495 return "unknown error in parse_pack_header";
497 case 0:
498 return NULL;
502 static const char *pack_lockfile;
504 static const char *unpack(void)
506 struct pack_header hdr;
507 const char *hdr_err;
508 char hdr_arg[38];
510 hdr_err = parse_pack_header(&hdr);
511 if (hdr_err)
512 return hdr_err;
513 snprintf(hdr_arg, sizeof(hdr_arg),
514 "--pack_header=%"PRIu32",%"PRIu32,
515 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
517 if (ntohl(hdr.hdr_entries) < unpack_limit) {
518 int code, i = 0;
519 const char *unpacker[4];
520 unpacker[i++] = "unpack-objects";
521 if (receive_fsck_objects)
522 unpacker[i++] = "--strict";
523 unpacker[i++] = hdr_arg;
524 unpacker[i++] = NULL;
525 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
526 if (!code)
527 return NULL;
528 run_status(code, unpacker[0]);
529 return "unpack-objects abnormal exit";
530 } else {
531 const char *keeper[7];
532 int s, status, i = 0;
533 char keep_arg[256];
534 struct child_process ip;
536 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
537 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
538 strcpy(keep_arg + s, "localhost");
540 keeper[i++] = "index-pack";
541 keeper[i++] = "--stdin";
542 if (receive_fsck_objects)
543 keeper[i++] = "--strict";
544 keeper[i++] = "--fix-thin";
545 keeper[i++] = hdr_arg;
546 keeper[i++] = keep_arg;
547 keeper[i++] = NULL;
548 memset(&ip, 0, sizeof(ip));
549 ip.argv = keeper;
550 ip.out = -1;
551 ip.git_cmd = 1;
552 status = start_command(&ip);
553 if (status) {
554 run_status(status, keeper[0]);
555 return "index-pack fork failed";
557 pack_lockfile = index_pack_lockfile(ip.out);
558 close(ip.out);
559 status = finish_command(&ip);
560 if (!status) {
561 reprepare_packed_git();
562 return NULL;
564 run_status(status, keeper[0]);
565 return "index-pack abnormal exit";
569 static void report(const char *unpack_status)
571 struct command *cmd;
572 packet_write(1, "unpack %s\n",
573 unpack_status ? unpack_status : "ok");
574 for (cmd = commands; cmd; cmd = cmd->next) {
575 if (!cmd->error_string)
576 packet_write(1, "ok %s\n",
577 cmd->ref_name);
578 else
579 packet_write(1, "ng %s %s\n",
580 cmd->ref_name, cmd->error_string);
582 packet_flush(1);
585 static int delete_only(struct command *cmd)
587 while (cmd) {
588 if (!is_null_sha1(cmd->new_sha1))
589 return 0;
590 cmd = cmd->next;
592 return 1;
595 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
597 char *other;
598 size_t len;
599 struct remote *remote;
600 struct transport *transport;
601 const struct ref *extra;
603 e->name[-1] = '\0';
604 other = xstrdup(make_absolute_path(e->base));
605 e->name[-1] = '/';
606 len = strlen(other);
608 while (other[len-1] == '/')
609 other[--len] = '\0';
610 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
611 return 0;
612 /* Is this a git repository with refs? */
613 memcpy(other + len - 8, "/refs", 6);
614 if (!is_directory(other))
615 return 0;
616 other[len - 8] = '\0';
617 remote = remote_get(other);
618 transport = transport_get(remote, other);
619 for (extra = transport_get_remote_refs(transport);
620 extra;
621 extra = extra->next) {
622 add_extra_ref(".have", extra->old_sha1, 0);
624 transport_disconnect(transport);
625 free(other);
626 return 0;
629 static void add_alternate_refs(void)
631 foreach_alt_odb(add_refs_from_alternate, NULL);
634 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
636 int i;
637 char *dir = NULL;
639 argv++;
640 for (i = 1; i < argc; i++) {
641 const char *arg = *argv++;
643 if (*arg == '-') {
644 /* Do flag handling here */
645 usage(receive_pack_usage);
647 if (dir)
648 usage(receive_pack_usage);
649 dir = xstrdup(arg);
651 if (!dir)
652 usage(receive_pack_usage);
654 setup_path();
656 if (!enter_repo(dir, 0))
657 die("'%s' does not appear to be a git repository", dir);
659 if (is_repository_shallow())
660 die("attempt to push into a shallow repository");
662 git_config(receive_pack_config, NULL);
664 if (0 <= transfer_unpack_limit)
665 unpack_limit = transfer_unpack_limit;
666 else if (0 <= receive_unpack_limit)
667 unpack_limit = receive_unpack_limit;
669 capabilities_to_send = (prefer_ofs_delta) ?
670 " report-status delete-refs ofs-delta " :
671 " report-status delete-refs ";
673 add_alternate_refs();
674 write_head_info();
675 clear_extra_refs();
677 /* EOF */
678 packet_flush(1);
680 read_head_info();
681 if (commands) {
682 const char *unpack_status = NULL;
684 if (!delete_only(commands))
685 unpack_status = unpack();
686 execute_commands(unpack_status);
687 if (pack_lockfile)
688 unlink_or_warn(pack_lockfile);
689 if (report_status)
690 report(unpack_status);
691 run_receive_hook(post_receive_hook);
692 run_update_post_hook(commands);
694 return 0;