Documentation: tiny git config manual tweaks
[git/wpalmer.git] / builtin-receive-pack.c
blob78c0e69cdc9fe2d21e83947932cb353c0553452e
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 int auto_update_server_info;
32 static int auto_gc = 1;
33 static const char *head_name;
34 static char *capabilities_to_send;
36 static enum deny_action parse_deny_action(const char *var, const char *value)
38 if (value) {
39 if (!strcasecmp(value, "ignore"))
40 return DENY_IGNORE;
41 if (!strcasecmp(value, "warn"))
42 return DENY_WARN;
43 if (!strcasecmp(value, "refuse"))
44 return DENY_REFUSE;
46 if (git_config_bool(var, value))
47 return DENY_REFUSE;
48 return DENY_IGNORE;
51 static int receive_pack_config(const char *var, const char *value, void *cb)
53 if (strcmp(var, "receive.denydeletes") == 0) {
54 deny_deletes = git_config_bool(var, value);
55 return 0;
58 if (strcmp(var, "receive.denynonfastforwards") == 0) {
59 deny_non_fast_forwards = git_config_bool(var, value);
60 return 0;
63 if (strcmp(var, "receive.unpacklimit") == 0) {
64 receive_unpack_limit = git_config_int(var, value);
65 return 0;
68 if (strcmp(var, "transfer.unpacklimit") == 0) {
69 transfer_unpack_limit = git_config_int(var, value);
70 return 0;
73 if (strcmp(var, "receive.fsckobjects") == 0) {
74 receive_fsck_objects = git_config_bool(var, value);
75 return 0;
78 if (!strcmp(var, "receive.denycurrentbranch")) {
79 deny_current_branch = parse_deny_action(var, value);
80 return 0;
83 if (strcmp(var, "receive.denydeletecurrent") == 0) {
84 deny_delete_current = parse_deny_action(var, value);
85 return 0;
88 if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
89 prefer_ofs_delta = git_config_bool(var, value);
90 return 0;
93 if (strcmp(var, "receive.updateserverinfo") == 0) {
94 auto_update_server_info = git_config_bool(var, value);
95 return 0;
98 if (strcmp(var, "receive.autogc") == 0) {
99 auto_gc = git_config_bool(var, value);
100 return 0;
103 return git_default_config(var, value, cb);
106 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
108 if (!capabilities_to_send)
109 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
110 else
111 packet_write(1, "%s %s%c%s\n",
112 sha1_to_hex(sha1), path, 0, capabilities_to_send);
113 capabilities_to_send = NULL;
114 return 0;
117 static void write_head_info(void)
119 for_each_ref(show_ref, NULL);
120 if (capabilities_to_send)
121 show_ref("capabilities^{}", null_sha1, 0, NULL);
125 struct command {
126 struct command *next;
127 const char *error_string;
128 unsigned char old_sha1[20];
129 unsigned char new_sha1[20];
130 char ref_name[FLEX_ARRAY]; /* more */
133 static struct command *commands;
135 static const char pre_receive_hook[] = "hooks/pre-receive";
136 static const char post_receive_hook[] = "hooks/post-receive";
138 static int run_receive_hook(const char *hook_name)
140 static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
141 struct command *cmd;
142 struct child_process proc;
143 const char *argv[2];
144 int have_input = 0, code;
146 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
147 if (!cmd->error_string)
148 have_input = 1;
151 if (!have_input || access(hook_name, X_OK) < 0)
152 return 0;
154 argv[0] = hook_name;
155 argv[1] = NULL;
157 memset(&proc, 0, sizeof(proc));
158 proc.argv = argv;
159 proc.in = -1;
160 proc.stdout_to_stderr = 1;
162 code = start_command(&proc);
163 if (code)
164 return code;
165 for (cmd = commands; cmd; cmd = cmd->next) {
166 if (!cmd->error_string) {
167 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
168 sha1_to_hex(cmd->old_sha1),
169 sha1_to_hex(cmd->new_sha1),
170 cmd->ref_name);
171 if (write_in_full(proc.in, buf, n) != n)
172 break;
175 close(proc.in);
176 return finish_command(&proc);
179 static int run_update_hook(struct command *cmd)
181 static const char update_hook[] = "hooks/update";
182 const char *argv[5];
184 if (access(update_hook, X_OK) < 0)
185 return 0;
187 argv[0] = update_hook;
188 argv[1] = cmd->ref_name;
189 argv[2] = sha1_to_hex(cmd->old_sha1);
190 argv[3] = sha1_to_hex(cmd->new_sha1);
191 argv[4] = NULL;
193 return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
194 RUN_COMMAND_STDOUT_TO_STDERR);
197 static int is_ref_checked_out(const char *ref)
199 if (is_bare_repository())
200 return 0;
202 if (!head_name)
203 return 0;
204 return !strcmp(head_name, ref);
207 static char *warn_unconfigured_deny_msg[] = {
208 "Updating the currently checked out branch may cause confusion,",
209 "as the index and work tree do not reflect changes that are in HEAD.",
210 "As a result, you may see the changes you just pushed into it",
211 "reverted when you run 'git diff' over there, and you may want",
212 "to run 'git reset --hard' before starting to work to recover.",
214 "You can set 'receive.denyCurrentBranch' configuration variable to",
215 "'refuse' in the remote repository to forbid pushing into its",
216 "current branch."
218 "To allow pushing into the current branch, you can set it to 'ignore';",
219 "but this is not recommended unless you arranged to update its work",
220 "tree to match what you pushed in some other way.",
222 "To squelch this message, you can set it to 'warn'.",
224 "Note that the default will change in a future version of git",
225 "to refuse updating the current branch unless you have the",
226 "configuration variable set to either 'ignore' or 'warn'."
229 static void warn_unconfigured_deny(void)
231 int i;
232 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
233 warning("%s", warn_unconfigured_deny_msg[i]);
236 static char *warn_unconfigured_deny_delete_current_msg[] = {
237 "Deleting the current branch can cause confusion by making the next",
238 "'git clone' not check out any file.",
240 "You can set 'receive.denyDeleteCurrent' configuration variable to",
241 "'refuse' in the remote repository to disallow deleting the current",
242 "branch.",
244 "You can set it to 'ignore' to allow such a delete without a warning.",
246 "To make this warning message less loud, you can set it to 'warn'.",
248 "Note that the default will change in a future version of git",
249 "to refuse deleting the current branch unless you have the",
250 "configuration variable set to either 'ignore' or 'warn'."
253 static void warn_unconfigured_deny_delete_current(void)
255 int i;
256 for (i = 0;
257 i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
258 i++)
259 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
262 static const char *update(struct command *cmd)
264 const char *name = cmd->ref_name;
265 unsigned char *old_sha1 = cmd->old_sha1;
266 unsigned char *new_sha1 = cmd->new_sha1;
267 struct ref_lock *lock;
269 /* only refs/... are allowed */
270 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
271 error("refusing to create funny ref '%s' remotely", name);
272 return "funny refname";
275 if (is_ref_checked_out(name)) {
276 switch (deny_current_branch) {
277 case DENY_IGNORE:
278 break;
279 case DENY_UNCONFIGURED:
280 case DENY_WARN:
281 warning("updating the current branch");
282 if (deny_current_branch == DENY_UNCONFIGURED)
283 warn_unconfigured_deny();
284 break;
285 case DENY_REFUSE:
286 error("refusing to update checked out branch: %s", name);
287 return "branch is currently checked out";
291 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
292 error("unpack should have generated %s, "
293 "but I can't find it!", sha1_to_hex(new_sha1));
294 return "bad pack";
297 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
298 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
299 error("denying ref deletion for %s", name);
300 return "deletion prohibited";
303 if (!strcmp(name, head_name)) {
304 switch (deny_delete_current) {
305 case DENY_IGNORE:
306 break;
307 case DENY_WARN:
308 case DENY_UNCONFIGURED:
309 if (deny_delete_current == DENY_UNCONFIGURED)
310 warn_unconfigured_deny_delete_current();
311 warning("deleting the current branch");
312 break;
313 case DENY_REFUSE:
314 error("refusing to delete the current branch: %s", name);
315 return "deletion of the current branch prohibited";
320 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
321 !is_null_sha1(old_sha1) &&
322 !prefixcmp(name, "refs/heads/")) {
323 struct object *old_object, *new_object;
324 struct commit *old_commit, *new_commit;
325 struct commit_list *bases, *ent;
327 old_object = parse_object(old_sha1);
328 new_object = parse_object(new_sha1);
330 if (!old_object || !new_object ||
331 old_object->type != OBJ_COMMIT ||
332 new_object->type != OBJ_COMMIT) {
333 error("bad sha1 objects for %s", name);
334 return "bad ref";
336 old_commit = (struct commit *)old_object;
337 new_commit = (struct commit *)new_object;
338 bases = get_merge_bases(old_commit, new_commit, 1);
339 for (ent = bases; ent; ent = ent->next)
340 if (!hashcmp(old_sha1, ent->item->object.sha1))
341 break;
342 free_commit_list(bases);
343 if (!ent) {
344 error("denying non-fast-forward %s"
345 " (you should pull first)", name);
346 return "non-fast-forward";
349 if (run_update_hook(cmd)) {
350 error("hook declined to update %s", name);
351 return "hook declined";
354 if (is_null_sha1(new_sha1)) {
355 if (!parse_object(old_sha1)) {
356 warning ("Allowing deletion of corrupt ref.");
357 old_sha1 = NULL;
359 if (delete_ref(name, old_sha1, 0)) {
360 error("failed to delete %s", name);
361 return "failed to delete";
363 return NULL; /* good */
365 else {
366 lock = lock_any_ref_for_update(name, old_sha1, 0);
367 if (!lock) {
368 error("failed to lock %s", name);
369 return "failed to lock";
371 if (write_ref_sha1(lock, new_sha1, "push")) {
372 return "failed to write"; /* error() already called */
374 return NULL; /* good */
378 static char update_post_hook[] = "hooks/post-update";
380 static void run_update_post_hook(struct command *cmd)
382 struct command *cmd_p;
383 int argc, status;
384 const char **argv;
386 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
387 if (cmd_p->error_string)
388 continue;
389 argc++;
391 if (!argc || access(update_post_hook, X_OK) < 0)
392 return;
393 argv = xmalloc(sizeof(*argv) * (2 + argc));
394 argv[0] = update_post_hook;
396 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
397 char *p;
398 if (cmd_p->error_string)
399 continue;
400 p = xmalloc(strlen(cmd_p->ref_name) + 1);
401 strcpy(p, cmd_p->ref_name);
402 argv[argc] = p;
403 argc++;
405 argv[argc] = NULL;
406 status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
407 | RUN_COMMAND_STDOUT_TO_STDERR);
410 static void execute_commands(const char *unpacker_error)
412 struct command *cmd = commands;
413 unsigned char sha1[20];
415 if (unpacker_error) {
416 while (cmd) {
417 cmd->error_string = "n/a (unpacker error)";
418 cmd = cmd->next;
420 return;
423 if (run_receive_hook(pre_receive_hook)) {
424 while (cmd) {
425 cmd->error_string = "pre-receive hook declined";
426 cmd = cmd->next;
428 return;
431 head_name = resolve_ref("HEAD", sha1, 0, NULL);
433 while (cmd) {
434 cmd->error_string = update(cmd);
435 cmd = cmd->next;
439 static void read_head_info(void)
441 struct command **p = &commands;
442 for (;;) {
443 static char line[1000];
444 unsigned char old_sha1[20], new_sha1[20];
445 struct command *cmd;
446 char *refname;
447 int len, reflen;
449 len = packet_read_line(0, line, sizeof(line));
450 if (!len)
451 break;
452 if (line[len-1] == '\n')
453 line[--len] = 0;
454 if (len < 83 ||
455 line[40] != ' ' ||
456 line[81] != ' ' ||
457 get_sha1_hex(line, old_sha1) ||
458 get_sha1_hex(line + 41, new_sha1))
459 die("protocol error: expected old/new/ref, got '%s'",
460 line);
462 refname = line + 82;
463 reflen = strlen(refname);
464 if (reflen + 82 < len) {
465 if (strstr(refname + reflen + 1, "report-status"))
466 report_status = 1;
468 cmd = xmalloc(sizeof(struct command) + len - 80);
469 hashcpy(cmd->old_sha1, old_sha1);
470 hashcpy(cmd->new_sha1, new_sha1);
471 memcpy(cmd->ref_name, line + 82, len - 81);
472 cmd->error_string = NULL;
473 cmd->next = NULL;
474 *p = cmd;
475 p = &cmd->next;
479 static const char *parse_pack_header(struct pack_header *hdr)
481 switch (read_pack_header(0, hdr)) {
482 case PH_ERROR_EOF:
483 return "eof before pack header was fully read";
485 case PH_ERROR_PACK_SIGNATURE:
486 return "protocol error (pack signature mismatch detected)";
488 case PH_ERROR_PROTOCOL:
489 return "protocol error (pack version unsupported)";
491 default:
492 return "unknown error in parse_pack_header";
494 case 0:
495 return NULL;
499 static const char *pack_lockfile;
501 static const char *unpack(void)
503 struct pack_header hdr;
504 const char *hdr_err;
505 char hdr_arg[38];
507 hdr_err = parse_pack_header(&hdr);
508 if (hdr_err)
509 return hdr_err;
510 snprintf(hdr_arg, sizeof(hdr_arg),
511 "--pack_header=%"PRIu32",%"PRIu32,
512 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
514 if (ntohl(hdr.hdr_entries) < unpack_limit) {
515 int code, i = 0;
516 const char *unpacker[4];
517 unpacker[i++] = "unpack-objects";
518 if (receive_fsck_objects)
519 unpacker[i++] = "--strict";
520 unpacker[i++] = hdr_arg;
521 unpacker[i++] = NULL;
522 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
523 if (!code)
524 return NULL;
525 return "unpack-objects abnormal exit";
526 } else {
527 const char *keeper[7];
528 int s, status, i = 0;
529 char keep_arg[256];
530 struct child_process ip;
532 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
533 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
534 strcpy(keep_arg + s, "localhost");
536 keeper[i++] = "index-pack";
537 keeper[i++] = "--stdin";
538 if (receive_fsck_objects)
539 keeper[i++] = "--strict";
540 keeper[i++] = "--fix-thin";
541 keeper[i++] = hdr_arg;
542 keeper[i++] = keep_arg;
543 keeper[i++] = NULL;
544 memset(&ip, 0, sizeof(ip));
545 ip.argv = keeper;
546 ip.out = -1;
547 ip.git_cmd = 1;
548 status = start_command(&ip);
549 if (status) {
550 return "index-pack fork failed";
552 pack_lockfile = index_pack_lockfile(ip.out);
553 close(ip.out);
554 status = finish_command(&ip);
555 if (!status) {
556 reprepare_packed_git();
557 return NULL;
559 return "index-pack abnormal exit";
563 static void report(const char *unpack_status)
565 struct command *cmd;
566 packet_write(1, "unpack %s\n",
567 unpack_status ? unpack_status : "ok");
568 for (cmd = commands; cmd; cmd = cmd->next) {
569 if (!cmd->error_string)
570 packet_write(1, "ok %s\n",
571 cmd->ref_name);
572 else
573 packet_write(1, "ng %s %s\n",
574 cmd->ref_name, cmd->error_string);
576 packet_flush(1);
579 static int delete_only(struct command *cmd)
581 while (cmd) {
582 if (!is_null_sha1(cmd->new_sha1))
583 return 0;
584 cmd = cmd->next;
586 return 1;
589 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
591 char *other;
592 size_t len;
593 struct remote *remote;
594 struct transport *transport;
595 const struct ref *extra;
597 e->name[-1] = '\0';
598 other = xstrdup(make_absolute_path(e->base));
599 e->name[-1] = '/';
600 len = strlen(other);
602 while (other[len-1] == '/')
603 other[--len] = '\0';
604 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
605 return 0;
606 /* Is this a git repository with refs? */
607 memcpy(other + len - 8, "/refs", 6);
608 if (!is_directory(other))
609 return 0;
610 other[len - 8] = '\0';
611 remote = remote_get(other);
612 transport = transport_get(remote, other);
613 for (extra = transport_get_remote_refs(transport);
614 extra;
615 extra = extra->next) {
616 add_extra_ref(".have", extra->old_sha1, 0);
618 transport_disconnect(transport);
619 free(other);
620 return 0;
623 static void add_alternate_refs(void)
625 foreach_alt_odb(add_refs_from_alternate, NULL);
628 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
630 int advertise_refs = 0;
631 int stateless_rpc = 0;
632 int i;
633 char *dir = NULL;
635 argv++;
636 for (i = 1; i < argc; i++) {
637 const char *arg = *argv++;
639 if (*arg == '-') {
640 if (!strcmp(arg, "--advertise-refs")) {
641 advertise_refs = 1;
642 continue;
644 if (!strcmp(arg, "--stateless-rpc")) {
645 stateless_rpc = 1;
646 continue;
649 usage(receive_pack_usage);
651 if (dir)
652 usage(receive_pack_usage);
653 dir = xstrdup(arg);
655 if (!dir)
656 usage(receive_pack_usage);
658 setup_path();
660 if (!enter_repo(dir, 0))
661 die("'%s' does not appear to be a git repository", dir);
663 if (is_repository_shallow())
664 die("attempt to push into a shallow repository");
666 git_config(receive_pack_config, NULL);
668 if (0 <= transfer_unpack_limit)
669 unpack_limit = transfer_unpack_limit;
670 else if (0 <= receive_unpack_limit)
671 unpack_limit = receive_unpack_limit;
673 capabilities_to_send = (prefer_ofs_delta) ?
674 " report-status delete-refs ofs-delta " :
675 " report-status delete-refs ";
677 if (advertise_refs || !stateless_rpc) {
678 add_alternate_refs();
679 write_head_info();
680 clear_extra_refs();
682 /* EOF */
683 packet_flush(1);
685 if (advertise_refs)
686 return 0;
688 read_head_info();
689 if (commands) {
690 const char *unpack_status = NULL;
692 if (!delete_only(commands))
693 unpack_status = unpack();
694 execute_commands(unpack_status);
695 if (pack_lockfile)
696 unlink_or_warn(pack_lockfile);
697 if (report_status)
698 report(unpack_status);
699 run_receive_hook(post_receive_hook);
700 run_update_post_hook(commands);
701 if (auto_gc) {
702 const char *argv_gc_auto[] = {
703 "gc", "--auto", "--quiet", NULL,
705 run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
707 if (auto_update_server_info)
708 update_server_info(0);
710 return 0;