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"
11
12static const char receive_pack_usage[] = "git receive-pack <git-dir>";
13
14enum deny_action {
15 DENY_UNCONFIGURED,
16 DENY_IGNORE,
17 DENY_WARN,
18 DENY_REFUSE,
19};
20
21static int deny_deletes;
22static int deny_non_fast_forwards;
23static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
24static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
25static int receive_fsck_objects;
26static int receive_unpack_limit = -1;
27static int transfer_unpack_limit = -1;
28static int unpack_limit = 100;
29static int report_status;
30static int prefer_ofs_delta = 1;
31static int auto_update_server_info;
32static int auto_gc = 1;
33static const char *head_name;
34static char *capabilities_to_send;
35
36static enum deny_action parse_deny_action(const char *var, const char *value)
37{
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;
45 }
46 if (git_config_bool(var, value))
47 return DENY_REFUSE;
48 return DENY_IGNORE;
49}
50
51static int receive_pack_config(const char *var, const char *value, void *cb)
52{
53 if (strcmp(var, "receive.denydeletes") == 0) {
54 deny_deletes = git_config_bool(var, value);
55 return 0;
56 }
57
58 if (strcmp(var, "receive.denynonfastforwards") == 0) {
59 deny_non_fast_forwards = git_config_bool(var, value);
60 return 0;
61 }
62
63 if (strcmp(var, "receive.unpacklimit") == 0) {
64 receive_unpack_limit = git_config_int(var, value);
65 return 0;
66 }
67
68 if (strcmp(var, "transfer.unpacklimit") == 0) {
69 transfer_unpack_limit = git_config_int(var, value);
70 return 0;
71 }
72
73 if (strcmp(var, "receive.fsckobjects") == 0) {
74 receive_fsck_objects = git_config_bool(var, value);
75 return 0;
76 }
77
78 if (!strcmp(var, "receive.denycurrentbranch")) {
79 deny_current_branch = parse_deny_action(var, value);
80 return 0;
81 }
82
83 if (strcmp(var, "receive.denydeletecurrent") == 0) {
84 deny_delete_current = parse_deny_action(var, value);
85 return 0;
86 }
87
88 if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
89 prefer_ofs_delta = git_config_bool(var, value);
90 return 0;
91 }
92
93 if (strcmp(var, "receive.updateserverinfo") == 0) {
94 auto_update_server_info = git_config_bool(var, value);
95 return 0;
96 }
97
98 if (strcmp(var, "receive.autogc") == 0) {
99 auto_gc = git_config_bool(var, value);
100 return 0;
101 }
102
103 return git_default_config(var, value, cb);
104}
105
106static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
107{
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;
115}
116
117static void write_head_info(void)
118{
119 for_each_ref(show_ref, NULL);
120 if (capabilities_to_send)
121 show_ref("capabilities^{}", null_sha1, 0, NULL);
122
123}
124
125struct 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 */
131};
132
133static struct command *commands;
134
135static const char pre_receive_hook[] = "hooks/pre-receive";
136static const char post_receive_hook[] = "hooks/post-receive";
137
138static int run_receive_hook(const char *hook_name)
139{
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;
145
146 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
147 if (!cmd->error_string)
148 have_input = 1;
149 }
150
151 if (!have_input || access(hook_name, X_OK) < 0)
152 return 0;
153
154 argv[0] = hook_name;
155 argv[1] = NULL;
156
157 memset(&proc, 0, sizeof(proc));
158 proc.argv = argv;
159 proc.in = -1;
160 proc.stdout_to_stderr = 1;
161
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;
173 }
174 }
175 close(proc.in);
176 return finish_command(&proc);
177}
178
179static int run_update_hook(struct command *cmd)
180{
181 static const char update_hook[] = "hooks/update";
182 const char *argv[5];
183
184 if (access(update_hook, X_OK) < 0)
185 return 0;
186
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;
192
193 return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
194 RUN_COMMAND_STDOUT_TO_STDERR);
195}
196
197static int is_ref_checked_out(const char *ref)
198{
199 if (is_bare_repository())
200 return 0;
201
202 if (!head_name)
203 return 0;
204 return !strcmp(head_name, ref);
205}
206
207static 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.",
213 "",
214 "You can set 'receive.denyCurrentBranch' configuration variable to",
215 "'refuse' in the remote repository to forbid pushing into its",
216 "current branch."
217 "",
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.",
221 "",
222 "To squelch this message, you can set it to 'warn'.",
223 "",
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'."
227};
228
229static void warn_unconfigured_deny(void)
230{
231 int i;
232 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
233 warning("%s", warn_unconfigured_deny_msg[i]);
234}
235
236static 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.",
239 "",
240 "You can set 'receive.denyDeleteCurrent' configuration variable to",
241 "'refuse' in the remote repository to disallow deleting the current",
242 "branch.",
243 "",
244 "You can set it to 'ignore' to allow such a delete without a warning.",
245 "",
246 "To make this warning message less loud, you can set it to 'warn'.",
247 "",
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'."
251};
252
253static void warn_unconfigured_deny_delete_current(void)
254{
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]);
260}
261
262static const char *update(struct command *cmd)
263{
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;
268
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";
273 }
274
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";
288 }
289 }
290
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";
295 }
296
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";
301 }
302
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";
316 }
317 }
318 }
319
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;
326
327 old_object = parse_object(old_sha1);
328 new_object = parse_object(new_sha1);
329
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";
335 }
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";
347 }
348 }
349 if (run_update_hook(cmd)) {
350 error("hook declined to update %s", name);
351 return "hook declined";
352 }
353
354 if (is_null_sha1(new_sha1)) {
355 if (!parse_object(old_sha1)) {
356 warning ("Allowing deletion of corrupt ref.");
357 old_sha1 = NULL;
358 }
359 if (delete_ref(name, old_sha1, 0)) {
360 error("failed to delete %s", name);
361 return "failed to delete";
362 }
363 return NULL; /* good */
364 }
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";
370 }
371 if (write_ref_sha1(lock, new_sha1, "push")) {
372 return "failed to write"; /* error() already called */
373 }
374 return NULL; /* good */
375 }
376}
377
378static char update_post_hook[] = "hooks/post-update";
379
380static void run_update_post_hook(struct command *cmd)
381{
382 struct command *cmd_p;
383 int argc, status;
384 const char **argv;
385
386 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
387 if (cmd_p->error_string)
388 continue;
389 argc++;
390 }
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;
395
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++;
404 }
405 argv[argc] = NULL;
406 status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
407 | RUN_COMMAND_STDOUT_TO_STDERR);
408}
409
410static void execute_commands(const char *unpacker_error)
411{
412 struct command *cmd = commands;
413 unsigned char sha1[20];
414
415 if (unpacker_error) {
416 while (cmd) {
417 cmd->error_string = "n/a (unpacker error)";
418 cmd = cmd->next;
419 }
420 return;
421 }
422
423 if (run_receive_hook(pre_receive_hook)) {
424 while (cmd) {
425 cmd->error_string = "pre-receive hook declined";
426 cmd = cmd->next;
427 }
428 return;
429 }
430
431 head_name = resolve_ref("HEAD", sha1, 0, NULL);
432
433 while (cmd) {
434 cmd->error_string = update(cmd);
435 cmd = cmd->next;
436 }
437}
438
439static void read_head_info(void)
440{
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;
448
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);
461
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;
467 }
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;
476 }
477}
478
479static const char *parse_pack_header(struct pack_header *hdr)
480{
481 switch (read_pack_header(0, hdr)) {
482 case PH_ERROR_EOF:
483 return "eof before pack header was fully read";
484
485 case PH_ERROR_PACK_SIGNATURE:
486 return "protocol error (pack signature mismatch detected)";
487
488 case PH_ERROR_PROTOCOL:
489 return "protocol error (pack version unsupported)";
490
491 default:
492 return "unknown error in parse_pack_header";
493
494 case 0:
495 return NULL;
496 }
497}
498
499static const char *pack_lockfile;
500
501static const char *unpack(void)
502{
503 struct pack_header hdr;
504 const char *hdr_err;
505 char hdr_arg[38];
506
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));
513
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;
531
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");
535
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";
551 }
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;
558 }
559 return "index-pack abnormal exit";
560 }
561}
562
563static void report(const char *unpack_status)
564{
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);
575 }
576 packet_flush(1);
577}
578
579static int delete_only(struct command *cmd)
580{
581 while (cmd) {
582 if (!is_null_sha1(cmd->new_sha1))
583 return 0;
584 cmd = cmd->next;
585 }
586 return 1;
587}
588
589static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
590{
591 char *other;
592 size_t len;
593 struct remote *remote;
594 struct transport *transport;
595 const struct ref *extra;
596
597 e->name[-1] = '\0';
598 other = xstrdup(make_absolute_path(e->base));
599 e->name[-1] = '/';
600 len = strlen(other);
601
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);
617 }
618 transport_disconnect(transport);
619 free(other);
620 return 0;
621}
622
623static void add_alternate_refs(void)
624{
625 foreach_alt_odb(add_refs_from_alternate, NULL);
626}
627
628int cmd_receive_pack(int argc, const char **argv, const char *prefix)
629{
630 int i;
631 char *dir = NULL;
632
633 argv++;
634 for (i = 1; i < argc; i++) {
635 const char *arg = *argv++;
636
637 if (*arg == '-') {
638 /* Do flag handling here */
639 usage(receive_pack_usage);
640 }
641 if (dir)
642 usage(receive_pack_usage);
643 dir = xstrdup(arg);
644 }
645 if (!dir)
646 usage(receive_pack_usage);
647
648 setup_path();
649
650 if (!enter_repo(dir, 0))
651 die("'%s' does not appear to be a git repository", dir);
652
653 if (is_repository_shallow())
654 die("attempt to push into a shallow repository");
655
656 git_config(receive_pack_config, NULL);
657
658 if (0 <= transfer_unpack_limit)
659 unpack_limit = transfer_unpack_limit;
660 else if (0 <= receive_unpack_limit)
661 unpack_limit = receive_unpack_limit;
662
663 capabilities_to_send = (prefer_ofs_delta) ?
664 " report-status delete-refs ofs-delta " :
665 " report-status delete-refs ";
666
667 add_alternate_refs();
668 write_head_info();
669 clear_extra_refs();
670
671 /* EOF */
672 packet_flush(1);
673
674 read_head_info();
675 if (commands) {
676 const char *unpack_status = NULL;
677
678 if (!delete_only(commands))
679 unpack_status = unpack();
680 execute_commands(unpack_status);
681 if (pack_lockfile)
682 unlink_or_warn(pack_lockfile);
683 if (report_status)
684 report(unpack_status);
685 run_receive_hook(post_receive_hook);
686 run_update_post_hook(commands);
687 if (auto_gc) {
688 const char *argv_gc_auto[] = {
689 "gc", "--auto", "--quiet", NULL,
690 };
691 run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
692 }
693 if (auto_update_server_info)
694 update_server_info(0);
695 }
696 return 0;
697}