WIP: do --submodule-summary using child_processes
[git/dscho.git] / builtin-receive-pack.c
blob892536b797923e63d933a6d70d0febdbd8b837d4
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_receive_hook(const char *hook_name)
128 static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
129 struct command *cmd;
130 struct child_process proc;
131 const char *argv[2];
132 int have_input = 0, code;
134 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
135 if (!cmd->error_string)
136 have_input = 1;
139 if (!have_input || access(hook_name, X_OK) < 0)
140 return 0;
142 argv[0] = hook_name;
143 argv[1] = NULL;
145 memset(&proc, 0, sizeof(proc));
146 proc.argv = argv;
147 proc.in = -1;
148 proc.stdout_to_stderr = 1;
150 code = start_command(&proc);
151 if (code)
152 return code;
153 for (cmd = commands; cmd; cmd = cmd->next) {
154 if (!cmd->error_string) {
155 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
156 sha1_to_hex(cmd->old_sha1),
157 sha1_to_hex(cmd->new_sha1),
158 cmd->ref_name);
159 if (write_in_full(proc.in, buf, n) != n)
160 break;
163 close(proc.in);
164 return finish_command(&proc);
167 static int run_update_hook(struct command *cmd)
169 static const char update_hook[] = "hooks/update";
170 const char *argv[5];
172 if (access(update_hook, X_OK) < 0)
173 return 0;
175 argv[0] = update_hook;
176 argv[1] = cmd->ref_name;
177 argv[2] = sha1_to_hex(cmd->old_sha1);
178 argv[3] = sha1_to_hex(cmd->new_sha1);
179 argv[4] = NULL;
181 return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
182 RUN_COMMAND_STDOUT_TO_STDERR);
185 static int is_ref_checked_out(const char *ref)
187 if (is_bare_repository())
188 return 0;
190 if (!head_name)
191 return 0;
192 return !strcmp(head_name, ref);
195 static char *refuse_unconfigured_deny_msg[] = {
196 "By default, updating the current branch in a non-bare repository",
197 "is denied, because it will make the index and work tree inconsistent",
198 "with what you pushed, and will require 'git reset --hard' to match",
199 "the work tree to HEAD.",
201 "You can set 'receive.denyCurrentBranch' configuration variable to",
202 "'ignore' or 'warn' in the remote repository to allow pushing into",
203 "its current branch; however, this is not recommended unless you",
204 "arranged to update its work tree to match what you pushed in some",
205 "other way.",
207 "To squelch this message and still keep the default behaviour, set",
208 "'receive.denyCurrentBranch' configuration variable to 'refuse'."
211 static void refuse_unconfigured_deny(void)
213 int i;
214 for (i = 0; i < ARRAY_SIZE(refuse_unconfigured_deny_msg); i++)
215 error("%s", refuse_unconfigured_deny_msg[i]);
218 static char *refuse_unconfigured_deny_delete_current_msg[] = {
219 "By default, deleting the current branch is denied, because the next",
220 "'git clone' won't result in any file checked out, causing confusion.",
222 "You can set 'receive.denyDeleteCurrent' configuration variable to",
223 "'warn' or 'ignore' in the remote repository to allow deleting the",
224 "current branch, with or without a warning message.",
226 "To squelch this message, you can set it to 'refuse'."
229 static void refuse_unconfigured_deny_delete_current(void)
231 int i;
232 for (i = 0;
233 i < ARRAY_SIZE(refuse_unconfigured_deny_delete_current_msg);
234 i++)
235 error("%s", refuse_unconfigured_deny_delete_current_msg[i]);
238 static const char *update(struct command *cmd)
240 const char *name = cmd->ref_name;
241 unsigned char *old_sha1 = cmd->old_sha1;
242 unsigned char *new_sha1 = cmd->new_sha1;
243 struct ref_lock *lock;
245 /* only refs/... are allowed */
246 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
247 error("refusing to create funny ref '%s' remotely", name);
248 return "funny refname";
251 if (is_ref_checked_out(name)) {
252 switch (deny_current_branch) {
253 case DENY_IGNORE:
254 break;
255 case DENY_WARN:
256 warning("updating the current branch");
257 break;
258 case DENY_REFUSE:
259 case DENY_UNCONFIGURED:
260 error("refusing to update checked out branch: %s", name);
261 if (deny_current_branch == DENY_UNCONFIGURED)
262 refuse_unconfigured_deny();
263 return "branch is currently checked out";
267 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
268 error("unpack should have generated %s, "
269 "but I can't find it!", sha1_to_hex(new_sha1));
270 return "bad pack";
273 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
274 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
275 error("denying ref deletion for %s", name);
276 return "deletion prohibited";
279 if (!strcmp(name, head_name)) {
280 switch (deny_delete_current) {
281 case DENY_IGNORE:
282 break;
283 case DENY_WARN:
284 warning("deleting the current branch");
285 break;
286 case DENY_REFUSE:
287 case DENY_UNCONFIGURED:
288 if (deny_delete_current == DENY_UNCONFIGURED)
289 refuse_unconfigured_deny_delete_current();
290 error("refusing to delete the current branch: %s", name);
291 return "deletion of the current branch prohibited";
296 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
297 !is_null_sha1(old_sha1) &&
298 !prefixcmp(name, "refs/heads/")) {
299 struct object *old_object, *new_object;
300 struct commit *old_commit, *new_commit;
301 struct commit_list *bases, *ent;
303 old_object = parse_object(old_sha1);
304 new_object = parse_object(new_sha1);
306 if (!old_object || !new_object ||
307 old_object->type != OBJ_COMMIT ||
308 new_object->type != OBJ_COMMIT) {
309 error("bad sha1 objects for %s", name);
310 return "bad ref";
312 old_commit = (struct commit *)old_object;
313 new_commit = (struct commit *)new_object;
314 bases = get_merge_bases(old_commit, new_commit, 1);
315 for (ent = bases; ent; ent = ent->next)
316 if (!hashcmp(old_sha1, ent->item->object.sha1))
317 break;
318 free_commit_list(bases);
319 if (!ent) {
320 error("denying non-fast forward %s"
321 " (you should pull first)", name);
322 return "non-fast forward";
325 if (run_update_hook(cmd)) {
326 error("hook declined to update %s", name);
327 return "hook declined";
330 if (is_null_sha1(new_sha1)) {
331 if (!parse_object(old_sha1)) {
332 warning ("Allowing deletion of corrupt ref.");
333 old_sha1 = NULL;
335 if (delete_ref(name, old_sha1, 0)) {
336 error("failed to delete %s", name);
337 return "failed to delete";
339 return NULL; /* good */
341 else {
342 lock = lock_any_ref_for_update(name, old_sha1, 0);
343 if (!lock) {
344 error("failed to lock %s", name);
345 return "failed to lock";
347 if (write_ref_sha1(lock, new_sha1, "push")) {
348 return "failed to write"; /* error() already called */
350 return NULL; /* good */
354 static char update_post_hook[] = "hooks/post-update";
356 static void run_update_post_hook(struct command *cmd)
358 struct command *cmd_p;
359 int argc, status;
360 const char **argv;
362 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
363 if (cmd_p->error_string)
364 continue;
365 argc++;
367 if (!argc || access(update_post_hook, X_OK) < 0)
368 return;
369 argv = xmalloc(sizeof(*argv) * (2 + argc));
370 argv[0] = update_post_hook;
372 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
373 char *p;
374 if (cmd_p->error_string)
375 continue;
376 p = xmalloc(strlen(cmd_p->ref_name) + 1);
377 strcpy(p, cmd_p->ref_name);
378 argv[argc] = p;
379 argc++;
381 argv[argc] = NULL;
382 status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
383 | RUN_COMMAND_STDOUT_TO_STDERR);
386 static void execute_commands(const char *unpacker_error)
388 struct command *cmd = commands;
389 unsigned char sha1[20];
391 if (unpacker_error) {
392 while (cmd) {
393 cmd->error_string = "n/a (unpacker error)";
394 cmd = cmd->next;
396 return;
399 if (run_receive_hook(pre_receive_hook)) {
400 while (cmd) {
401 cmd->error_string = "pre-receive hook declined";
402 cmd = cmd->next;
404 return;
407 head_name = resolve_ref("HEAD", sha1, 0, NULL);
409 while (cmd) {
410 cmd->error_string = update(cmd);
411 cmd = cmd->next;
415 static void read_head_info(void)
417 struct command **p = &commands;
418 for (;;) {
419 static char line[1000];
420 unsigned char old_sha1[20], new_sha1[20];
421 struct command *cmd;
422 char *refname;
423 int len, reflen;
425 len = packet_read_line(0, line, sizeof(line));
426 if (!len)
427 break;
428 if (line[len-1] == '\n')
429 line[--len] = 0;
430 if (len < 83 ||
431 line[40] != ' ' ||
432 line[81] != ' ' ||
433 get_sha1_hex(line, old_sha1) ||
434 get_sha1_hex(line + 41, new_sha1))
435 die("protocol error: expected old/new/ref, got '%s'",
436 line);
438 refname = line + 82;
439 reflen = strlen(refname);
440 if (reflen + 82 < len) {
441 if (strstr(refname + reflen + 1, "report-status"))
442 report_status = 1;
444 cmd = xmalloc(sizeof(struct command) + len - 80);
445 hashcpy(cmd->old_sha1, old_sha1);
446 hashcpy(cmd->new_sha1, new_sha1);
447 memcpy(cmd->ref_name, line + 82, len - 81);
448 cmd->error_string = NULL;
449 cmd->next = NULL;
450 *p = cmd;
451 p = &cmd->next;
455 static const char *parse_pack_header(struct pack_header *hdr)
457 switch (read_pack_header(0, hdr)) {
458 case PH_ERROR_EOF:
459 return "eof before pack header was fully read";
461 case PH_ERROR_PACK_SIGNATURE:
462 return "protocol error (pack signature mismatch detected)";
464 case PH_ERROR_PROTOCOL:
465 return "protocol error (pack version unsupported)";
467 default:
468 return "unknown error in parse_pack_header";
470 case 0:
471 return NULL;
475 static const char *pack_lockfile;
477 static const char *unpack(void)
479 struct pack_header hdr;
480 const char *hdr_err;
481 char hdr_arg[38];
483 hdr_err = parse_pack_header(&hdr);
484 if (hdr_err)
485 return hdr_err;
486 snprintf(hdr_arg, sizeof(hdr_arg),
487 "--pack_header=%"PRIu32",%"PRIu32,
488 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
490 if (ntohl(hdr.hdr_entries) < unpack_limit) {
491 int code, i = 0;
492 const char *unpacker[4];
493 unpacker[i++] = "unpack-objects";
494 if (receive_fsck_objects)
495 unpacker[i++] = "--strict";
496 unpacker[i++] = hdr_arg;
497 unpacker[i++] = NULL;
498 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
499 if (!code)
500 return NULL;
501 return "unpack-objects abnormal exit";
502 } else {
503 const char *keeper[7];
504 int s, status, i = 0;
505 char keep_arg[256];
506 struct child_process ip;
508 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
509 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
510 strcpy(keep_arg + s, "localhost");
512 keeper[i++] = "index-pack";
513 keeper[i++] = "--stdin";
514 if (receive_fsck_objects)
515 keeper[i++] = "--strict";
516 keeper[i++] = "--fix-thin";
517 keeper[i++] = hdr_arg;
518 keeper[i++] = keep_arg;
519 keeper[i++] = NULL;
520 memset(&ip, 0, sizeof(ip));
521 ip.argv = keeper;
522 ip.out = -1;
523 ip.git_cmd = 1;
524 status = start_command(&ip);
525 if (status) {
526 return "index-pack fork failed";
528 pack_lockfile = index_pack_lockfile(ip.out);
529 close(ip.out);
530 status = finish_command(&ip);
531 if (!status) {
532 reprepare_packed_git();
533 return NULL;
535 return "index-pack abnormal exit";
539 static void report(const char *unpack_status)
541 struct command *cmd;
542 packet_write(1, "unpack %s\n",
543 unpack_status ? unpack_status : "ok");
544 for (cmd = commands; cmd; cmd = cmd->next) {
545 if (!cmd->error_string)
546 packet_write(1, "ok %s\n",
547 cmd->ref_name);
548 else
549 packet_write(1, "ng %s %s\n",
550 cmd->ref_name, cmd->error_string);
552 packet_flush(1);
555 static int delete_only(struct command *cmd)
557 while (cmd) {
558 if (!is_null_sha1(cmd->new_sha1))
559 return 0;
560 cmd = cmd->next;
562 return 1;
565 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
567 char *other;
568 size_t len;
569 struct remote *remote;
570 struct transport *transport;
571 const struct ref *extra;
573 e->name[-1] = '\0';
574 other = xstrdup(make_absolute_path(e->base));
575 e->name[-1] = '/';
576 len = strlen(other);
578 while (other[len-1] == '/')
579 other[--len] = '\0';
580 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
581 return 0;
582 /* Is this a git repository with refs? */
583 memcpy(other + len - 8, "/refs", 6);
584 if (!is_directory(other))
585 return 0;
586 other[len - 8] = '\0';
587 remote = remote_get(other);
588 transport = transport_get(remote, other);
589 for (extra = transport_get_remote_refs(transport);
590 extra;
591 extra = extra->next) {
592 add_extra_ref(".have", extra->old_sha1, 0);
594 transport_disconnect(transport);
595 free(other);
596 return 0;
599 static void add_alternate_refs(void)
601 foreach_alt_odb(add_refs_from_alternate, NULL);
604 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
606 int i;
607 char *dir = NULL;
609 argv++;
610 for (i = 1; i < argc; i++) {
611 const char *arg = *argv++;
613 if (*arg == '-') {
614 /* Do flag handling here */
615 usage(receive_pack_usage);
617 if (dir)
618 usage(receive_pack_usage);
619 dir = xstrdup(arg);
621 if (!dir)
622 usage(receive_pack_usage);
624 setup_path();
626 if (!enter_repo(dir, 0))
627 die("'%s' does not appear to be a git repository", dir);
629 if (is_repository_shallow())
630 die("attempt to push into a shallow repository");
632 git_config(receive_pack_config, NULL);
634 if (0 <= transfer_unpack_limit)
635 unpack_limit = transfer_unpack_limit;
636 else if (0 <= receive_unpack_limit)
637 unpack_limit = receive_unpack_limit;
639 capabilities_to_send = (prefer_ofs_delta) ?
640 " report-status delete-refs ofs-delta " :
641 " report-status delete-refs ";
643 add_alternate_refs();
644 write_head_info();
645 clear_extra_refs();
647 /* EOF */
648 packet_flush(1);
650 read_head_info();
651 if (commands) {
652 const char *unpack_status = NULL;
654 if (!delete_only(commands))
655 unpack_status = unpack();
656 execute_commands(unpack_status);
657 if (pack_lockfile)
658 unlink_or_warn(pack_lockfile);
659 if (report_status)
660 report(unpack_status);
661 run_receive_hook(post_receive_hook);
662 run_update_post_hook(commands);
664 return 0;