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 const char *head_name;
32static char *capabilities_to_send;
33
34static enum deny_action parse_deny_action(const char *var, const char *value)
35{
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;
43 }
44 if (git_config_bool(var, value))
45 return DENY_REFUSE;
46 return DENY_IGNORE;
47}
48
49static int receive_pack_config(const char *var, const char *value, void *cb)
50{
51 if (strcmp(var, "receive.denydeletes") == 0) {
52 deny_deletes = git_config_bool(var, value);
53 return 0;
54 }
55
56 if (strcmp(var, "receive.denynonfastforwards") == 0) {
57 deny_non_fast_forwards = git_config_bool(var, value);
58 return 0;
59 }
60
61 if (strcmp(var, "receive.unpacklimit") == 0) {
62 receive_unpack_limit = git_config_int(var, value);
63 return 0;
64 }
65
66 if (strcmp(var, "transfer.unpacklimit") == 0) {
67 transfer_unpack_limit = git_config_int(var, value);
68 return 0;
69 }
70
71 if (strcmp(var, "receive.fsckobjects") == 0) {
72 receive_fsck_objects = git_config_bool(var, value);
73 return 0;
74 }
75
76 if (!strcmp(var, "receive.denycurrentbranch")) {
77 deny_current_branch = parse_deny_action(var, value);
78 return 0;
79 }
80
81 if (strcmp(var, "receive.denydeletecurrent") == 0) {
82 deny_delete_current = parse_deny_action(var, value);
83 return 0;
84 }
85
86 if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
87 prefer_ofs_delta = git_config_bool(var, value);
88 return 0;
89 }
90
91 return git_default_config(var, value, cb);
92}
93
94static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
95{
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;
103}
104
105static void write_head_info(void)
106{
107 for_each_ref(show_ref, NULL);
108 if (capabilities_to_send)
109 show_ref("capabilities^{}", null_sha1, 0, NULL);
110
111}
112
113struct 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 */
119};
120
121static struct command *commands;
122
123static const char pre_receive_hook[] = "hooks/pre-receive";
124static const char post_receive_hook[] = "hooks/post-receive";
125
126static int run_status(int code, const char *cmd_name)
127{
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;
148 }
149}
150
151static int run_receive_hook(const char *hook_name)
152{
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;
158
159 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
160 if (!cmd->error_string)
161 have_input = 1;
162 }
163
164 if (!have_input || access(hook_name, X_OK) < 0)
165 return 0;
166
167 argv[0] = hook_name;
168 argv[1] = NULL;
169
170 memset(&proc, 0, sizeof(proc));
171 proc.argv = argv;
172 proc.in = -1;
173 proc.stdout_to_stderr = 1;
174
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;
186 }
187 }
188 close(proc.in);
189 return run_status(finish_command(&proc), hook_name);
190}
191
192static int run_update_hook(struct command *cmd)
193{
194 static const char update_hook[] = "hooks/update";
195 const char *argv[5];
196
197 if (access(update_hook, X_OK) < 0)
198 return 0;
199
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;
205
206 return run_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
207 RUN_COMMAND_STDOUT_TO_STDERR),
208 update_hook);
209}
210
211static int is_ref_checked_out(const char *ref)
212{
213 if (is_bare_repository())
214 return 0;
215
216 if (!head_name)
217 return 0;
218 return !strcmp(head_name, ref);
219}
220
221static 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.",
226 "",
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.",
232 "",
233 "To squelch this message and still keep the default behaviour, set",
234 "'receive.denyCurrentBranch' configuration variable to 'refuse'."
235};
236
237static void refuse_unconfigured_deny(void)
238{
239 int i;
240 for (i = 0; i < ARRAY_SIZE(refuse_unconfigured_deny_msg); i++)
241 error("%s", refuse_unconfigured_deny_msg[i]);
242}
243
244static char *warn_unconfigured_deny_delete_current_msg[] = {
245 "Deleting the current branch can cause confusion by making the next",
246 "'git clone' not check out any file.",
247 "",
248 "You can set 'receive.denyDeleteCurrent' configuration variable to",
249 "'refuse' in the remote repository to disallow deleting the current",
250 "branch.",
251 "",
252 "You can set it to 'ignore' to allow such a delete without a warning.",
253 "",
254 "To make this warning message less loud, you can set it to 'warn'.",
255 "",
256 "Note that the default will change in a future version of git",
257 "to refuse deleting the current branch unless you have the",
258 "configuration variable set to either 'ignore' or 'warn'."
259};
260
261static void warn_unconfigured_deny_delete_current(void)
262{
263 int i;
264 for (i = 0;
265 i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
266 i++)
267 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
268}
269
270static const char *update(struct command *cmd)
271{
272 const char *name = cmd->ref_name;
273 unsigned char *old_sha1 = cmd->old_sha1;
274 unsigned char *new_sha1 = cmd->new_sha1;
275 struct ref_lock *lock;
276
277 /* only refs/... are allowed */
278 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
279 error("refusing to create funny ref '%s' remotely", name);
280 return "funny refname";
281 }
282
283 if (is_ref_checked_out(name)) {
284 switch (deny_current_branch) {
285 case DENY_IGNORE:
286 break;
287 case DENY_WARN:
288 warning("updating the current branch");
289 break;
290 case DENY_REFUSE:
291 case DENY_UNCONFIGURED:
292 error("refusing to update checked out branch: %s", name);
293 if (deny_current_branch == DENY_UNCONFIGURED)
294 refuse_unconfigured_deny();
295 return "branch is currently checked out";
296 }
297 }
298
299 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
300 error("unpack should have generated %s, "
301 "but I can't find it!", sha1_to_hex(new_sha1));
302 return "bad pack";
303 }
304
305 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
306 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
307 error("denying ref deletion for %s", name);
308 return "deletion prohibited";
309 }
310
311 if (!strcmp(name, head_name)) {
312 switch (deny_delete_current) {
313 case DENY_IGNORE:
314 break;
315 case DENY_WARN:
316 case DENY_UNCONFIGURED:
317 if (deny_delete_current == DENY_UNCONFIGURED)
318 warn_unconfigured_deny_delete_current();
319 warning("deleting the current branch");
320 break;
321 case DENY_REFUSE:
322 error("refusing to delete the current branch: %s", name);
323 return "deletion of the current branch prohibited";
324 }
325 }
326 }
327
328 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
329 !is_null_sha1(old_sha1) &&
330 !prefixcmp(name, "refs/heads/")) {
331 struct object *old_object, *new_object;
332 struct commit *old_commit, *new_commit;
333 struct commit_list *bases, *ent;
334
335 old_object = parse_object(old_sha1);
336 new_object = parse_object(new_sha1);
337
338 if (!old_object || !new_object ||
339 old_object->type != OBJ_COMMIT ||
340 new_object->type != OBJ_COMMIT) {
341 error("bad sha1 objects for %s", name);
342 return "bad ref";
343 }
344 old_commit = (struct commit *)old_object;
345 new_commit = (struct commit *)new_object;
346 bases = get_merge_bases(old_commit, new_commit, 1);
347 for (ent = bases; ent; ent = ent->next)
348 if (!hashcmp(old_sha1, ent->item->object.sha1))
349 break;
350 free_commit_list(bases);
351 if (!ent) {
352 error("denying non-fast forward %s"
353 " (you should pull first)", name);
354 return "non-fast forward";
355 }
356 }
357 if (run_update_hook(cmd)) {
358 error("hook declined to update %s", name);
359 return "hook declined";
360 }
361
362 if (is_null_sha1(new_sha1)) {
363 if (!parse_object(old_sha1)) {
364 warning ("Allowing deletion of corrupt ref.");
365 old_sha1 = NULL;
366 }
367 if (delete_ref(name, old_sha1, 0)) {
368 error("failed to delete %s", name);
369 return "failed to delete";
370 }
371 return NULL; /* good */
372 }
373 else {
374 lock = lock_any_ref_for_update(name, old_sha1, 0);
375 if (!lock) {
376 error("failed to lock %s", name);
377 return "failed to lock";
378 }
379 if (write_ref_sha1(lock, new_sha1, "push")) {
380 return "failed to write"; /* error() already called */
381 }
382 return NULL; /* good */
383 }
384}
385
386static char update_post_hook[] = "hooks/post-update";
387
388static void run_update_post_hook(struct command *cmd)
389{
390 struct command *cmd_p;
391 int argc, status;
392 const char **argv;
393
394 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
395 if (cmd_p->error_string)
396 continue;
397 argc++;
398 }
399 if (!argc || access(update_post_hook, X_OK) < 0)
400 return;
401 argv = xmalloc(sizeof(*argv) * (2 + argc));
402 argv[0] = update_post_hook;
403
404 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
405 char *p;
406 if (cmd_p->error_string)
407 continue;
408 p = xmalloc(strlen(cmd_p->ref_name) + 1);
409 strcpy(p, cmd_p->ref_name);
410 argv[argc] = p;
411 argc++;
412 }
413 argv[argc] = NULL;
414 status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
415 | RUN_COMMAND_STDOUT_TO_STDERR);
416 run_status(status, update_post_hook);
417}
418
419static void execute_commands(const char *unpacker_error)
420{
421 struct command *cmd = commands;
422 unsigned char sha1[20];
423
424 if (unpacker_error) {
425 while (cmd) {
426 cmd->error_string = "n/a (unpacker error)";
427 cmd = cmd->next;
428 }
429 return;
430 }
431
432 if (run_receive_hook(pre_receive_hook)) {
433 while (cmd) {
434 cmd->error_string = "pre-receive hook declined";
435 cmd = cmd->next;
436 }
437 return;
438 }
439
440 head_name = resolve_ref("HEAD", sha1, 0, NULL);
441
442 while (cmd) {
443 cmd->error_string = update(cmd);
444 cmd = cmd->next;
445 }
446}
447
448static void read_head_info(void)
449{
450 struct command **p = &commands;
451 for (;;) {
452 static char line[1000];
453 unsigned char old_sha1[20], new_sha1[20];
454 struct command *cmd;
455 char *refname;
456 int len, reflen;
457
458 len = packet_read_line(0, line, sizeof(line));
459 if (!len)
460 break;
461 if (line[len-1] == '\n')
462 line[--len] = 0;
463 if (len < 83 ||
464 line[40] != ' ' ||
465 line[81] != ' ' ||
466 get_sha1_hex(line, old_sha1) ||
467 get_sha1_hex(line + 41, new_sha1))
468 die("protocol error: expected old/new/ref, got '%s'",
469 line);
470
471 refname = line + 82;
472 reflen = strlen(refname);
473 if (reflen + 82 < len) {
474 if (strstr(refname + reflen + 1, "report-status"))
475 report_status = 1;
476 }
477 cmd = xmalloc(sizeof(struct command) + len - 80);
478 hashcpy(cmd->old_sha1, old_sha1);
479 hashcpy(cmd->new_sha1, new_sha1);
480 memcpy(cmd->ref_name, line + 82, len - 81);
481 cmd->error_string = NULL;
482 cmd->next = NULL;
483 *p = cmd;
484 p = &cmd->next;
485 }
486}
487
488static const char *parse_pack_header(struct pack_header *hdr)
489{
490 switch (read_pack_header(0, hdr)) {
491 case PH_ERROR_EOF:
492 return "eof before pack header was fully read";
493
494 case PH_ERROR_PACK_SIGNATURE:
495 return "protocol error (pack signature mismatch detected)";
496
497 case PH_ERROR_PROTOCOL:
498 return "protocol error (pack version unsupported)";
499
500 default:
501 return "unknown error in parse_pack_header";
502
503 case 0:
504 return NULL;
505 }
506}
507
508static const char *pack_lockfile;
509
510static const char *unpack(void)
511{
512 struct pack_header hdr;
513 const char *hdr_err;
514 char hdr_arg[38];
515
516 hdr_err = parse_pack_header(&hdr);
517 if (hdr_err)
518 return hdr_err;
519 snprintf(hdr_arg, sizeof(hdr_arg),
520 "--pack_header=%"PRIu32",%"PRIu32,
521 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
522
523 if (ntohl(hdr.hdr_entries) < unpack_limit) {
524 int code, i = 0;
525 const char *unpacker[4];
526 unpacker[i++] = "unpack-objects";
527 if (receive_fsck_objects)
528 unpacker[i++] = "--strict";
529 unpacker[i++] = hdr_arg;
530 unpacker[i++] = NULL;
531 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
532 if (!code)
533 return NULL;
534 run_status(code, unpacker[0]);
535 return "unpack-objects abnormal exit";
536 } else {
537 const char *keeper[7];
538 int s, status, i = 0;
539 char keep_arg[256];
540 struct child_process ip;
541
542 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
543 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
544 strcpy(keep_arg + s, "localhost");
545
546 keeper[i++] = "index-pack";
547 keeper[i++] = "--stdin";
548 if (receive_fsck_objects)
549 keeper[i++] = "--strict";
550 keeper[i++] = "--fix-thin";
551 keeper[i++] = hdr_arg;
552 keeper[i++] = keep_arg;
553 keeper[i++] = NULL;
554 memset(&ip, 0, sizeof(ip));
555 ip.argv = keeper;
556 ip.out = -1;
557 ip.git_cmd = 1;
558 status = start_command(&ip);
559 if (status) {
560 run_status(status, keeper[0]);
561 return "index-pack fork failed";
562 }
563 pack_lockfile = index_pack_lockfile(ip.out);
564 close(ip.out);
565 status = finish_command(&ip);
566 if (!status) {
567 reprepare_packed_git();
568 return NULL;
569 }
570 run_status(status, keeper[0]);
571 return "index-pack abnormal exit";
572 }
573}
574
575static void report(const char *unpack_status)
576{
577 struct command *cmd;
578 packet_write(1, "unpack %s\n",
579 unpack_status ? unpack_status : "ok");
580 for (cmd = commands; cmd; cmd = cmd->next) {
581 if (!cmd->error_string)
582 packet_write(1, "ok %s\n",
583 cmd->ref_name);
584 else
585 packet_write(1, "ng %s %s\n",
586 cmd->ref_name, cmd->error_string);
587 }
588 packet_flush(1);
589}
590
591static int delete_only(struct command *cmd)
592{
593 while (cmd) {
594 if (!is_null_sha1(cmd->new_sha1))
595 return 0;
596 cmd = cmd->next;
597 }
598 return 1;
599}
600
601static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
602{
603 char *other;
604 size_t len;
605 struct remote *remote;
606 struct transport *transport;
607 const struct ref *extra;
608
609 e->name[-1] = '\0';
610 other = xstrdup(make_absolute_path(e->base));
611 e->name[-1] = '/';
612 len = strlen(other);
613
614 while (other[len-1] == '/')
615 other[--len] = '\0';
616 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
617 return 0;
618 /* Is this a git repository with refs? */
619 memcpy(other + len - 8, "/refs", 6);
620 if (!is_directory(other))
621 return 0;
622 other[len - 8] = '\0';
623 remote = remote_get(other);
624 transport = transport_get(remote, other);
625 for (extra = transport_get_remote_refs(transport);
626 extra;
627 extra = extra->next) {
628 add_extra_ref(".have", extra->old_sha1, 0);
629 }
630 transport_disconnect(transport);
631 free(other);
632 return 0;
633}
634
635static void add_alternate_refs(void)
636{
637 foreach_alt_odb(add_refs_from_alternate, NULL);
638}
639
640int cmd_receive_pack(int argc, const char **argv, const char *prefix)
641{
642 int i;
643 char *dir = NULL;
644
645 argv++;
646 for (i = 1; i < argc; i++) {
647 const char *arg = *argv++;
648
649 if (*arg == '-') {
650 /* Do flag handling here */
651 usage(receive_pack_usage);
652 }
653 if (dir)
654 usage(receive_pack_usage);
655 dir = xstrdup(arg);
656 }
657 if (!dir)
658 usage(receive_pack_usage);
659
660 setup_path();
661
662 if (!enter_repo(dir, 0))
663 die("'%s' does not appear to be a git repository", dir);
664
665 if (is_repository_shallow())
666 die("attempt to push into a shallow repository");
667
668 git_config(receive_pack_config, NULL);
669
670 if (0 <= transfer_unpack_limit)
671 unpack_limit = transfer_unpack_limit;
672 else if (0 <= receive_unpack_limit)
673 unpack_limit = receive_unpack_limit;
674
675 capabilities_to_send = (prefer_ofs_delta) ?
676 " report-status delete-refs ofs-delta " :
677 " report-status delete-refs ";
678
679 add_alternate_refs();
680 write_head_info();
681 clear_extra_refs();
682
683 /* EOF */
684 packet_flush(1);
685
686 read_head_info();
687 if (commands) {
688 const char *unpack_status = NULL;
689
690 if (!delete_only(commands))
691 unpack_status = unpack();
692 execute_commands(unpack_status);
693 if (pack_lockfile)
694 unlink_or_warn(pack_lockfile);
695 if (report_status)
696 report(unpack_status);
697 run_receive_hook(post_receive_hook);
698 run_update_post_hook(commands);
699 }
700 return 0;
701}