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 = 0;
22static int deny_non_fast_forwards = 0;
23static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
24static int receive_fsck_objects;
25static int receive_unpack_limit = -1;
26static int transfer_unpack_limit = -1;
27static int unpack_limit = 100;
28static int report_status;
29
30static char capabilities[] = " report-status delete-refs ";
31static int capabilities_sent;
32
33static enum deny_action parse_deny_action(const char *var, const char *value)
34{
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;
42 }
43 if (git_config_bool(var, value))
44 return DENY_REFUSE;
45 return DENY_IGNORE;
46}
47
48static int receive_pack_config(const char *var, const char *value, void *cb)
49{
50 if (strcmp(var, "receive.denydeletes") == 0) {
51 deny_deletes = git_config_bool(var, value);
52 return 0;
53 }
54
55 if (strcmp(var, "receive.denynonfastforwards") == 0) {
56 deny_non_fast_forwards = git_config_bool(var, value);
57 return 0;
58 }
59
60 if (strcmp(var, "receive.unpacklimit") == 0) {
61 receive_unpack_limit = git_config_int(var, value);
62 return 0;
63 }
64
65 if (strcmp(var, "transfer.unpacklimit") == 0) {
66 transfer_unpack_limit = git_config_int(var, value);
67 return 0;
68 }
69
70 if (strcmp(var, "receive.fsckobjects") == 0) {
71 receive_fsck_objects = git_config_bool(var, value);
72 return 0;
73 }
74
75 if (!strcmp(var, "receive.denycurrentbranch")) {
76 deny_current_branch = parse_deny_action(var, value);
77 return 0;
78 }
79
80 return git_default_config(var, value, cb);
81}
82
83static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
84{
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;
92}
93
94static void write_head_info(void)
95{
96 for_each_ref(show_ref, NULL);
97 if (!capabilities_sent)
98 show_ref("capabilities^{}", null_sha1, 0, NULL);
99
100}
101
102struct 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 */
108};
109
110static struct command *commands;
111
112static const char pre_receive_hook[] = "hooks/pre-receive";
113static const char post_receive_hook[] = "hooks/post-receive";
114
115static int hook_status(int code, const char *hook_name)
116{
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;
137 }
138}
139
140static int run_receive_hook(const char *hook_name)
141{
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;
147
148 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
149 if (!cmd->error_string)
150 have_input = 1;
151 }
152
153 if (!have_input || access(hook_name, X_OK) < 0)
154 return 0;
155
156 argv[0] = hook_name;
157 argv[1] = NULL;
158
159 memset(&proc, 0, sizeof(proc));
160 proc.argv = argv;
161 proc.in = -1;
162 proc.stdout_to_stderr = 1;
163
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;
175 }
176 }
177 close(proc.in);
178 return hook_status(finish_command(&proc), hook_name);
179}
180
181static int run_update_hook(struct command *cmd)
182{
183 static const char update_hook[] = "hooks/update";
184 struct child_process proc;
185 const char *argv[5];
186
187 if (access(update_hook, X_OK) < 0)
188 return 0;
189
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;
195
196 memset(&proc, 0, sizeof(proc));
197 proc.argv = argv;
198 proc.no_stdin = 1;
199 proc.stdout_to_stderr = 1;
200
201 return hook_status(run_command(&proc), update_hook);
202}
203
204static int is_ref_checked_out(const char *ref)
205{
206 unsigned char sha1[20];
207 const char *head;
208
209 if (is_bare_repository())
210 return 0;
211
212 head = resolve_ref("HEAD", sha1, 0, NULL);
213 if (!head)
214 return 0;
215 return !strcmp(head, ref);
216}
217
218static 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.",
224 "",
225 "You can set 'receive.denyCurrentBranch' configuration variable to",
226 "'refuse' in the remote repository to forbid pushing into its",
227 "current branch."
228 "",
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.",
232 "",
233 "To squelch this message, you can set it to 'warn'.",
234 "",
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'."
238};
239
240static void warn_unconfigured_deny(void)
241{
242 int i;
243 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
244 warning(warn_unconfigured_deny_msg[i]);
245}
246
247static const char *update(struct command *cmd)
248{
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;
253
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";
258 }
259
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";
273 }
274 }
275
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";
280 }
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";
286 }
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;
293
294 old_object = parse_object(old_sha1);
295 new_object = parse_object(new_sha1);
296
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";
302 }
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";
314 }
315 }
316 if (run_update_hook(cmd)) {
317 error("hook declined to update %s", name);
318 return "hook declined";
319 }
320
321 if (is_null_sha1(new_sha1)) {
322 if (!parse_object(old_sha1)) {
323 warning ("Allowing deletion of corrupt ref.");
324 old_sha1 = NULL;
325 }
326 if (delete_ref(name, old_sha1, 0)) {
327 error("failed to delete %s", name);
328 return "failed to delete";
329 }
330 return NULL; /* good */
331 }
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";
337 }
338 if (write_ref_sha1(lock, new_sha1, "push")) {
339 return "failed to write"; /* error() already called */
340 }
341 return NULL; /* good */
342 }
343}
344
345static char update_post_hook[] = "hooks/post-update";
346
347static void run_update_post_hook(struct command *cmd)
348{
349 struct command *cmd_p;
350 int argc;
351 const char **argv;
352
353 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
354 if (cmd_p->error_string)
355 continue;
356 argc++;
357 }
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;
362
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++;
371 }
372 argv[argc] = NULL;
373 run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
374 | RUN_COMMAND_STDOUT_TO_STDERR);
375}
376
377static void execute_commands(const char *unpacker_error)
378{
379 struct command *cmd = commands;
380
381 if (unpacker_error) {
382 while (cmd) {
383 cmd->error_string = "n/a (unpacker error)";
384 cmd = cmd->next;
385 }
386 return;
387 }
388
389 if (run_receive_hook(pre_receive_hook)) {
390 while (cmd) {
391 cmd->error_string = "pre-receive hook declined";
392 cmd = cmd->next;
393 }
394 return;
395 }
396
397 while (cmd) {
398 cmd->error_string = update(cmd);
399 cmd = cmd->next;
400 }
401}
402
403static void read_head_info(void)
404{
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;
412
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);
425
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;
431 }
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;
440 }
441}
442
443static const char *parse_pack_header(struct pack_header *hdr)
444{
445 switch (read_pack_header(0, hdr)) {
446 case PH_ERROR_EOF:
447 return "eof before pack header was fully read";
448
449 case PH_ERROR_PACK_SIGNATURE:
450 return "protocol error (pack signature mismatch detected)";
451
452 case PH_ERROR_PROTOCOL:
453 return "protocol error (pack version unsupported)";
454
455 default:
456 return "unknown error in parse_pack_header";
457
458 case 0:
459 return NULL;
460 }
461}
462
463static const char *pack_lockfile;
464
465static const char *unpack(void)
466{
467 struct pack_header hdr;
468 const char *hdr_err;
469 char hdr_arg[38];
470
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));
477
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";
504 }
505 } else {
506 const char *keeper[7];
507 int s, status, i = 0;
508 char keep_arg[256];
509 struct child_process ip;
510
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");
514
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;
535 }
536 return "index-pack abnormal exit";
537 }
538}
539
540static void report(const char *unpack_status)
541{
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);
552 }
553 packet_flush(1);
554}
555
556static int delete_only(struct command *cmd)
557{
558 while (cmd) {
559 if (!is_null_sha1(cmd->new_sha1))
560 return 0;
561 cmd = cmd->next;
562 }
563 return 1;
564}
565
566static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
567{
568 char *other;
569 size_t len;
570 struct remote *remote;
571 struct transport *transport;
572 const struct ref *extra;
573
574 e->name[-1] = '\0';
575 other = xstrdup(make_absolute_path(e->base));
576 e->name[-1] = '/';
577 len = strlen(other);
578
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);
594 }
595 transport_disconnect(transport);
596 free(other);
597 return 0;
598}
599
600static void add_alternate_refs(void)
601{
602 foreach_alt_odb(add_refs_from_alternate, NULL);
603}
604
605int cmd_receive_pack(int argc, const char **argv, const char *prefix)
606{
607 int i;
608 char *dir = NULL;
609
610 argv++;
611 for (i = 1; i < argc; i++) {
612 const char *arg = *argv++;
613
614 if (*arg == '-') {
615 /* Do flag handling here */
616 usage(receive_pack_usage);
617 }
618 if (dir)
619 usage(receive_pack_usage);
620 dir = xstrdup(arg);
621 }
622 if (!dir)
623 usage(receive_pack_usage);
624
625 setup_path();
626
627 if (!enter_repo(dir, 0))
628 die("'%s': unable to chdir or not a git archive", dir);
629
630 if (is_repository_shallow())
631 die("attempt to push into a shallow repository");
632
633 git_config(receive_pack_config, NULL);
634
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;
639
640 add_alternate_refs();
641 write_head_info();
642 clear_extra_refs();
643
644 /* EOF */
645 packet_flush(1);
646
647 read_head_info();
648 if (commands) {
649 const char *unpack_status = NULL;
650
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);
660 }
661 return 0;
662}