Merge branch 'maint'
[git/jrn.git] / builtin-receive-pack.c
blob6de186c397fcd5eaab2331db56546acab5f545f4
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 = 0;
22 static int deny_non_fast_forwards = 0;
23 static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
24 static int receive_fsck_objects;
25 static int receive_unpack_limit = -1;
26 static int transfer_unpack_limit = -1;
27 static int unpack_limit = 100;
28 static int report_status;
30 static char capabilities[] = " report-status delete-refs ";
31 static int capabilities_sent;
33 static enum deny_action parse_deny_action(const char *var, const char *value)
35 if (value) {
36 if (!strcasecmp(value, "ignore"))
37 return DENY_IGNORE;
38 if (!strcasecmp(value, "warn"))
39 return DENY_WARN;
40 if (!strcasecmp(value, "refuse"))
41 return DENY_REFUSE;
43 if (git_config_bool(var, value))
44 return DENY_REFUSE;
45 return DENY_IGNORE;
48 static int receive_pack_config(const char *var, const char *value, void *cb)
50 if (strcmp(var, "receive.denydeletes") == 0) {
51 deny_deletes = git_config_bool(var, value);
52 return 0;
55 if (strcmp(var, "receive.denynonfastforwards") == 0) {
56 deny_non_fast_forwards = git_config_bool(var, value);
57 return 0;
60 if (strcmp(var, "receive.unpacklimit") == 0) {
61 receive_unpack_limit = git_config_int(var, value);
62 return 0;
65 if (strcmp(var, "transfer.unpacklimit") == 0) {
66 transfer_unpack_limit = git_config_int(var, value);
67 return 0;
70 if (strcmp(var, "receive.fsckobjects") == 0) {
71 receive_fsck_objects = git_config_bool(var, value);
72 return 0;
75 if (!strcmp(var, "receive.denycurrentbranch")) {
76 deny_current_branch = parse_deny_action(var, value);
77 return 0;
80 return git_default_config(var, value, cb);
83 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
85 if (capabilities_sent)
86 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
87 else
88 packet_write(1, "%s %s%c%s\n",
89 sha1_to_hex(sha1), path, 0, capabilities);
90 capabilities_sent = 1;
91 return 0;
94 static void write_head_info(void)
96 for_each_ref(show_ref, NULL);
97 if (!capabilities_sent)
98 show_ref("capabilities^{}", null_sha1, 0, NULL);
102 struct command {
103 struct command *next;
104 const char *error_string;
105 unsigned char old_sha1[20];
106 unsigned char new_sha1[20];
107 char ref_name[FLEX_ARRAY]; /* more */
110 static struct command *commands;
112 static const char pre_receive_hook[] = "hooks/pre-receive";
113 static const char post_receive_hook[] = "hooks/post-receive";
115 static int hook_status(int code, const char *hook_name)
117 switch (code) {
118 case 0:
119 return 0;
120 case -ERR_RUN_COMMAND_FORK:
121 return error("hook fork failed");
122 case -ERR_RUN_COMMAND_EXEC:
123 return error("hook execute failed");
124 case -ERR_RUN_COMMAND_PIPE:
125 return error("hook pipe failed");
126 case -ERR_RUN_COMMAND_WAITPID:
127 return error("waitpid failed");
128 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
129 return error("waitpid is confused");
130 case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
131 return error("%s died of signal", hook_name);
132 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
133 return error("%s died strangely", hook_name);
134 default:
135 error("%s exited with error code %d", hook_name, -code);
136 return -code;
140 static int run_receive_hook(const char *hook_name)
142 static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
143 struct command *cmd;
144 struct child_process proc;
145 const char *argv[2];
146 int have_input = 0, code;
148 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
149 if (!cmd->error_string)
150 have_input = 1;
153 if (!have_input || access(hook_name, X_OK) < 0)
154 return 0;
156 argv[0] = hook_name;
157 argv[1] = NULL;
159 memset(&proc, 0, sizeof(proc));
160 proc.argv = argv;
161 proc.in = -1;
162 proc.stdout_to_stderr = 1;
164 code = start_command(&proc);
165 if (code)
166 return hook_status(code, hook_name);
167 for (cmd = commands; cmd; cmd = cmd->next) {
168 if (!cmd->error_string) {
169 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
170 sha1_to_hex(cmd->old_sha1),
171 sha1_to_hex(cmd->new_sha1),
172 cmd->ref_name);
173 if (write_in_full(proc.in, buf, n) != n)
174 break;
177 close(proc.in);
178 return hook_status(finish_command(&proc), hook_name);
181 static int run_update_hook(struct command *cmd)
183 static const char update_hook[] = "hooks/update";
184 struct child_process proc;
185 const char *argv[5];
187 if (access(update_hook, X_OK) < 0)
188 return 0;
190 argv[0] = update_hook;
191 argv[1] = cmd->ref_name;
192 argv[2] = sha1_to_hex(cmd->old_sha1);
193 argv[3] = sha1_to_hex(cmd->new_sha1);
194 argv[4] = NULL;
196 memset(&proc, 0, sizeof(proc));
197 proc.argv = argv;
198 proc.no_stdin = 1;
199 proc.stdout_to_stderr = 1;
201 return hook_status(run_command(&proc), update_hook);
204 static int is_ref_checked_out(const char *ref)
206 unsigned char sha1[20];
207 const char *head;
209 if (is_bare_repository())
210 return 0;
212 head = resolve_ref("HEAD", sha1, 0, NULL);
213 if (!head)
214 return 0;
215 return !strcmp(head, ref);
218 static char *warn_unconfigured_deny_msg[] = {
219 "Updating the currently checked out branch may cause confusion,",
220 "as the index and work tree do not reflect changes that are in HEAD.",
221 "As a result, you may see the changes you just pushed into it",
222 "reverted when you run 'git diff' over there, and you may want",
223 "to run 'git reset --hard' before starting to work to recover.",
225 "You can set 'receive.denyCurrentBranch' configuration variable to",
226 "'refuse' in the remote repository to forbid pushing into its",
227 "current branch."
229 "To allow pushing into the current branch, you can set it to 'ignore';",
230 "but this is not recommended unless you arranged to update its work",
231 "tree to match what you pushed in some other way.",
233 "To squelch this message, you can set it to 'warn'.",
235 "Note that the default will change in a future version of git",
236 "to refuse updating the current branch unless you have the",
237 "configuration variable set to either 'ignore' or 'warn'."
240 static void warn_unconfigured_deny(void)
242 int i;
243 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
244 warning(warn_unconfigured_deny_msg[i]);
247 static const char *update(struct command *cmd)
249 const char *name = cmd->ref_name;
250 unsigned char *old_sha1 = cmd->old_sha1;
251 unsigned char *new_sha1 = cmd->new_sha1;
252 struct ref_lock *lock;
254 /* only refs/... are allowed */
255 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
256 error("refusing to create funny ref '%s' remotely", name);
257 return "funny refname";
260 if (is_ref_checked_out(name)) {
261 switch (deny_current_branch) {
262 case DENY_IGNORE:
263 break;
264 case DENY_UNCONFIGURED:
265 case DENY_WARN:
266 warning("updating the current branch");
267 if (deny_current_branch == DENY_UNCONFIGURED)
268 warn_unconfigured_deny();
269 break;
270 case DENY_REFUSE:
271 error("refusing to update checked out branch: %s", name);
272 return "branch is currently checked out";
276 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
277 error("unpack should have generated %s, "
278 "but I can't find it!", sha1_to_hex(new_sha1));
279 return "bad pack";
281 if (deny_deletes && is_null_sha1(new_sha1) &&
282 !is_null_sha1(old_sha1) &&
283 !prefixcmp(name, "refs/heads/")) {
284 error("denying ref deletion for %s", name);
285 return "deletion prohibited";
287 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
288 !is_null_sha1(old_sha1) &&
289 !prefixcmp(name, "refs/heads/")) {
290 struct object *old_object, *new_object;
291 struct commit *old_commit, *new_commit;
292 struct commit_list *bases, *ent;
294 old_object = parse_object(old_sha1);
295 new_object = parse_object(new_sha1);
297 if (!old_object || !new_object ||
298 old_object->type != OBJ_COMMIT ||
299 new_object->type != OBJ_COMMIT) {
300 error("bad sha1 objects for %s", name);
301 return "bad ref";
303 old_commit = (struct commit *)old_object;
304 new_commit = (struct commit *)new_object;
305 bases = get_merge_bases(old_commit, new_commit, 1);
306 for (ent = bases; ent; ent = ent->next)
307 if (!hashcmp(old_sha1, ent->item->object.sha1))
308 break;
309 free_commit_list(bases);
310 if (!ent) {
311 error("denying non-fast forward %s"
312 " (you should pull first)", name);
313 return "non-fast forward";
316 if (run_update_hook(cmd)) {
317 error("hook declined to update %s", name);
318 return "hook declined";
321 if (is_null_sha1(new_sha1)) {
322 if (!parse_object(old_sha1)) {
323 warning ("Allowing deletion of corrupt ref.");
324 old_sha1 = NULL;
326 if (delete_ref(name, old_sha1, 0)) {
327 error("failed to delete %s", name);
328 return "failed to delete";
330 return NULL; /* good */
332 else {
333 lock = lock_any_ref_for_update(name, old_sha1, 0);
334 if (!lock) {
335 error("failed to lock %s", name);
336 return "failed to lock";
338 if (write_ref_sha1(lock, new_sha1, "push")) {
339 return "failed to write"; /* error() already called */
341 return NULL; /* good */
345 static char update_post_hook[] = "hooks/post-update";
347 static void run_update_post_hook(struct command *cmd)
349 struct command *cmd_p;
350 int argc;
351 const char **argv;
353 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
354 if (cmd_p->error_string)
355 continue;
356 argc++;
358 if (!argc || access(update_post_hook, X_OK) < 0)
359 return;
360 argv = xmalloc(sizeof(*argv) * (2 + argc));
361 argv[0] = update_post_hook;
363 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
364 char *p;
365 if (cmd_p->error_string)
366 continue;
367 p = xmalloc(strlen(cmd_p->ref_name) + 1);
368 strcpy(p, cmd_p->ref_name);
369 argv[argc] = p;
370 argc++;
372 argv[argc] = NULL;
373 run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
374 | RUN_COMMAND_STDOUT_TO_STDERR);
377 static void execute_commands(const char *unpacker_error)
379 struct command *cmd = commands;
381 if (unpacker_error) {
382 while (cmd) {
383 cmd->error_string = "n/a (unpacker error)";
384 cmd = cmd->next;
386 return;
389 if (run_receive_hook(pre_receive_hook)) {
390 while (cmd) {
391 cmd->error_string = "pre-receive hook declined";
392 cmd = cmd->next;
394 return;
397 while (cmd) {
398 cmd->error_string = update(cmd);
399 cmd = cmd->next;
403 static void read_head_info(void)
405 struct command **p = &commands;
406 for (;;) {
407 static char line[1000];
408 unsigned char old_sha1[20], new_sha1[20];
409 struct command *cmd;
410 char *refname;
411 int len, reflen;
413 len = packet_read_line(0, line, sizeof(line));
414 if (!len)
415 break;
416 if (line[len-1] == '\n')
417 line[--len] = 0;
418 if (len < 83 ||
419 line[40] != ' ' ||
420 line[81] != ' ' ||
421 get_sha1_hex(line, old_sha1) ||
422 get_sha1_hex(line + 41, new_sha1))
423 die("protocol error: expected old/new/ref, got '%s'",
424 line);
426 refname = line + 82;
427 reflen = strlen(refname);
428 if (reflen + 82 < len) {
429 if (strstr(refname + reflen + 1, "report-status"))
430 report_status = 1;
432 cmd = xmalloc(sizeof(struct command) + len - 80);
433 hashcpy(cmd->old_sha1, old_sha1);
434 hashcpy(cmd->new_sha1, new_sha1);
435 memcpy(cmd->ref_name, line + 82, len - 81);
436 cmd->error_string = NULL;
437 cmd->next = NULL;
438 *p = cmd;
439 p = &cmd->next;
443 static const char *parse_pack_header(struct pack_header *hdr)
445 switch (read_pack_header(0, hdr)) {
446 case PH_ERROR_EOF:
447 return "eof before pack header was fully read";
449 case PH_ERROR_PACK_SIGNATURE:
450 return "protocol error (pack signature mismatch detected)";
452 case PH_ERROR_PROTOCOL:
453 return "protocol error (pack version unsupported)";
455 default:
456 return "unknown error in parse_pack_header";
458 case 0:
459 return NULL;
463 static const char *pack_lockfile;
465 static const char *unpack(void)
467 struct pack_header hdr;
468 const char *hdr_err;
469 char hdr_arg[38];
471 hdr_err = parse_pack_header(&hdr);
472 if (hdr_err)
473 return hdr_err;
474 snprintf(hdr_arg, sizeof(hdr_arg),
475 "--pack_header=%"PRIu32",%"PRIu32,
476 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
478 if (ntohl(hdr.hdr_entries) < unpack_limit) {
479 int code, i = 0;
480 const char *unpacker[4];
481 unpacker[i++] = "unpack-objects";
482 if (receive_fsck_objects)
483 unpacker[i++] = "--strict";
484 unpacker[i++] = hdr_arg;
485 unpacker[i++] = NULL;
486 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
487 switch (code) {
488 case 0:
489 return NULL;
490 case -ERR_RUN_COMMAND_FORK:
491 return "unpack fork failed";
492 case -ERR_RUN_COMMAND_EXEC:
493 return "unpack execute failed";
494 case -ERR_RUN_COMMAND_WAITPID:
495 return "waitpid failed";
496 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
497 return "waitpid is confused";
498 case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
499 return "unpacker died of signal";
500 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
501 return "unpacker died strangely";
502 default:
503 return "unpacker exited with error code";
505 } else {
506 const char *keeper[7];
507 int s, status, i = 0;
508 char keep_arg[256];
509 struct child_process ip;
511 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
512 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
513 strcpy(keep_arg + s, "localhost");
515 keeper[i++] = "index-pack";
516 keeper[i++] = "--stdin";
517 if (receive_fsck_objects)
518 keeper[i++] = "--strict";
519 keeper[i++] = "--fix-thin";
520 keeper[i++] = hdr_arg;
521 keeper[i++] = keep_arg;
522 keeper[i++] = NULL;
523 memset(&ip, 0, sizeof(ip));
524 ip.argv = keeper;
525 ip.out = -1;
526 ip.git_cmd = 1;
527 if (start_command(&ip))
528 return "index-pack fork failed";
529 pack_lockfile = index_pack_lockfile(ip.out);
530 close(ip.out);
531 status = finish_command(&ip);
532 if (!status) {
533 reprepare_packed_git();
534 return NULL;
536 return "index-pack abnormal exit";
540 static void report(const char *unpack_status)
542 struct command *cmd;
543 packet_write(1, "unpack %s\n",
544 unpack_status ? unpack_status : "ok");
545 for (cmd = commands; cmd; cmd = cmd->next) {
546 if (!cmd->error_string)
547 packet_write(1, "ok %s\n",
548 cmd->ref_name);
549 else
550 packet_write(1, "ng %s %s\n",
551 cmd->ref_name, cmd->error_string);
553 packet_flush(1);
556 static int delete_only(struct command *cmd)
558 while (cmd) {
559 if (!is_null_sha1(cmd->new_sha1))
560 return 0;
561 cmd = cmd->next;
563 return 1;
566 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
568 char *other;
569 size_t len;
570 struct remote *remote;
571 struct transport *transport;
572 const struct ref *extra;
574 e->name[-1] = '\0';
575 other = xstrdup(make_absolute_path(e->base));
576 e->name[-1] = '/';
577 len = strlen(other);
579 while (other[len-1] == '/')
580 other[--len] = '\0';
581 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
582 return 0;
583 /* Is this a git repository with refs? */
584 memcpy(other + len - 8, "/refs", 6);
585 if (!is_directory(other))
586 return 0;
587 other[len - 8] = '\0';
588 remote = remote_get(other);
589 transport = transport_get(remote, other);
590 for (extra = transport_get_remote_refs(transport);
591 extra;
592 extra = extra->next) {
593 add_extra_ref(".have", extra->old_sha1, 0);
595 transport_disconnect(transport);
596 free(other);
597 return 0;
600 static void add_alternate_refs(void)
602 foreach_alt_odb(add_refs_from_alternate, NULL);
605 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
607 int i;
608 char *dir = NULL;
610 argv++;
611 for (i = 1; i < argc; i++) {
612 const char *arg = *argv++;
614 if (*arg == '-') {
615 /* Do flag handling here */
616 usage(receive_pack_usage);
618 if (dir)
619 usage(receive_pack_usage);
620 dir = xstrdup(arg);
622 if (!dir)
623 usage(receive_pack_usage);
625 setup_path();
627 if (!enter_repo(dir, 0))
628 die("'%s': unable to chdir or not a git archive", dir);
630 if (is_repository_shallow())
631 die("attempt to push into a shallow repository");
633 git_config(receive_pack_config, NULL);
635 if (0 <= transfer_unpack_limit)
636 unpack_limit = transfer_unpack_limit;
637 else if (0 <= receive_unpack_limit)
638 unpack_limit = receive_unpack_limit;
640 add_alternate_refs();
641 write_head_info();
642 clear_extra_refs();
644 /* EOF */
645 packet_flush(1);
647 read_head_info();
648 if (commands) {
649 const char *unpack_status = NULL;
651 if (!delete_only(commands))
652 unpack_status = unpack();
653 execute_commands(unpack_status);
654 if (pack_lockfile)
655 unlink(pack_lockfile);
656 if (report_status)
657 report(unpack_status);
658 run_receive_hook(post_receive_hook);
659 run_update_post_hook(commands);
661 return 0;