c85507b12291de48b5306bc9949815bf50dd9dcf
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 if (code > 0)
129 error("%s exited with error code %d", cmd_name, code);
130 return code;
131}
132
133static int run_receive_hook(const char *hook_name)
134{
135 static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
136 struct command *cmd;
137 struct child_process proc;
138 const char *argv[2];
139 int have_input = 0, code;
140
141 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
142 if (!cmd->error_string)
143 have_input = 1;
144 }
145
146 if (!have_input || access(hook_name, X_OK) < 0)
147 return 0;
148
149 argv[0] = hook_name;
150 argv[1] = NULL;
151
152 memset(&proc, 0, sizeof(proc));
153 proc.argv = argv;
154 proc.in = -1;
155 proc.stdout_to_stderr = 1;
156
157 code = start_command(&proc);
158 if (code)
159 return run_status(code, hook_name);
160 for (cmd = commands; cmd; cmd = cmd->next) {
161 if (!cmd->error_string) {
162 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
163 sha1_to_hex(cmd->old_sha1),
164 sha1_to_hex(cmd->new_sha1),
165 cmd->ref_name);
166 if (write_in_full(proc.in, buf, n) != n)
167 break;
168 }
169 }
170 close(proc.in);
171 return run_status(finish_command(&proc), hook_name);
172}
173
174static int run_update_hook(struct command *cmd)
175{
176 static const char update_hook[] = "hooks/update";
177 const char *argv[5];
178
179 if (access(update_hook, X_OK) < 0)
180 return 0;
181
182 argv[0] = update_hook;
183 argv[1] = cmd->ref_name;
184 argv[2] = sha1_to_hex(cmd->old_sha1);
185 argv[3] = sha1_to_hex(cmd->new_sha1);
186 argv[4] = NULL;
187
188 return run_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
189 RUN_COMMAND_STDOUT_TO_STDERR),
190 update_hook);
191}
192
193static int is_ref_checked_out(const char *ref)
194{
195 if (is_bare_repository())
196 return 0;
197
198 if (!head_name)
199 return 0;
200 return !strcmp(head_name, ref);
201}
202
203static char *warn_unconfigured_deny_msg[] = {
204 "Updating the currently checked out branch may cause confusion,",
205 "as the index and work tree do not reflect changes that are in HEAD.",
206 "As a result, you may see the changes you just pushed into it",
207 "reverted when you run 'git diff' over there, and you may want",
208 "to run 'git reset --hard' before starting to work to recover.",
209 "",
210 "You can set 'receive.denyCurrentBranch' configuration variable to",
211 "'refuse' in the remote repository to forbid pushing into its",
212 "current branch."
213 "",
214 "To allow pushing into the current branch, you can set it to 'ignore';",
215 "but this is not recommended unless you arranged to update its work",
216 "tree to match what you pushed in some other way.",
217 "",
218 "To squelch this message, you can set it to 'warn'.",
219 "",
220 "Note that the default will change in a future version of git",
221 "to refuse updating the current branch unless you have the",
222 "configuration variable set to either 'ignore' or 'warn'."
223};
224
225static void warn_unconfigured_deny(void)
226{
227 int i;
228 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
229 warning("%s", warn_unconfigured_deny_msg[i]);
230}
231
232static char *warn_unconfigured_deny_delete_current_msg[] = {
233 "Deleting the current branch can cause confusion by making the next",
234 "'git clone' not check out any file.",
235 "",
236 "You can set 'receive.denyDeleteCurrent' configuration variable to",
237 "'refuse' in the remote repository to disallow deleting the current",
238 "branch.",
239 "",
240 "You can set it to 'ignore' to allow such a delete without a warning.",
241 "",
242 "To make this warning message less loud, you can set it to 'warn'.",
243 "",
244 "Note that the default will change in a future version of git",
245 "to refuse deleting the current branch unless you have the",
246 "configuration variable set to either 'ignore' or 'warn'."
247};
248
249static void warn_unconfigured_deny_delete_current(void)
250{
251 int i;
252 for (i = 0;
253 i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
254 i++)
255 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
256}
257
258static const char *update(struct command *cmd)
259{
260 const char *name = cmd->ref_name;
261 unsigned char *old_sha1 = cmd->old_sha1;
262 unsigned char *new_sha1 = cmd->new_sha1;
263 struct ref_lock *lock;
264
265 /* only refs/... are allowed */
266 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
267 error("refusing to create funny ref '%s' remotely", name);
268 return "funny refname";
269 }
270
271 if (is_ref_checked_out(name)) {
272 switch (deny_current_branch) {
273 case DENY_IGNORE:
274 break;
275 case DENY_UNCONFIGURED:
276 case DENY_WARN:
277 warning("updating the current branch");
278 if (deny_current_branch == DENY_UNCONFIGURED)
279 warn_unconfigured_deny();
280 break;
281 case DENY_REFUSE:
282 error("refusing to update checked out branch: %s", name);
283 return "branch is currently checked out";
284 }
285 }
286
287 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
288 error("unpack should have generated %s, "
289 "but I can't find it!", sha1_to_hex(new_sha1));
290 return "bad pack";
291 }
292
293 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
294 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
295 error("denying ref deletion for %s", name);
296 return "deletion prohibited";
297 }
298
299 if (!strcmp(name, head_name)) {
300 switch (deny_delete_current) {
301 case DENY_IGNORE:
302 break;
303 case DENY_WARN:
304 case DENY_UNCONFIGURED:
305 if (deny_delete_current == DENY_UNCONFIGURED)
306 warn_unconfigured_deny_delete_current();
307 warning("deleting the current branch");
308 break;
309 case DENY_REFUSE:
310 error("refusing to delete the current branch: %s", name);
311 return "deletion of the current branch prohibited";
312 }
313 }
314 }
315
316 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
317 !is_null_sha1(old_sha1) &&
318 !prefixcmp(name, "refs/heads/")) {
319 struct object *old_object, *new_object;
320 struct commit *old_commit, *new_commit;
321 struct commit_list *bases, *ent;
322
323 old_object = parse_object(old_sha1);
324 new_object = parse_object(new_sha1);
325
326 if (!old_object || !new_object ||
327 old_object->type != OBJ_COMMIT ||
328 new_object->type != OBJ_COMMIT) {
329 error("bad sha1 objects for %s", name);
330 return "bad ref";
331 }
332 old_commit = (struct commit *)old_object;
333 new_commit = (struct commit *)new_object;
334 bases = get_merge_bases(old_commit, new_commit, 1);
335 for (ent = bases; ent; ent = ent->next)
336 if (!hashcmp(old_sha1, ent->item->object.sha1))
337 break;
338 free_commit_list(bases);
339 if (!ent) {
340 error("denying non-fast forward %s"
341 " (you should pull first)", name);
342 return "non-fast forward";
343 }
344 }
345 if (run_update_hook(cmd)) {
346 error("hook declined to update %s", name);
347 return "hook declined";
348 }
349
350 if (is_null_sha1(new_sha1)) {
351 if (!parse_object(old_sha1)) {
352 warning ("Allowing deletion of corrupt ref.");
353 old_sha1 = NULL;
354 }
355 if (delete_ref(name, old_sha1, 0)) {
356 error("failed to delete %s", name);
357 return "failed to delete";
358 }
359 return NULL; /* good */
360 }
361 else {
362 lock = lock_any_ref_for_update(name, old_sha1, 0);
363 if (!lock) {
364 error("failed to lock %s", name);
365 return "failed to lock";
366 }
367 if (write_ref_sha1(lock, new_sha1, "push")) {
368 return "failed to write"; /* error() already called */
369 }
370 return NULL; /* good */
371 }
372}
373
374static char update_post_hook[] = "hooks/post-update";
375
376static void run_update_post_hook(struct command *cmd)
377{
378 struct command *cmd_p;
379 int argc, status;
380 const char **argv;
381
382 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
383 if (cmd_p->error_string)
384 continue;
385 argc++;
386 }
387 if (!argc || access(update_post_hook, X_OK) < 0)
388 return;
389 argv = xmalloc(sizeof(*argv) * (2 + argc));
390 argv[0] = update_post_hook;
391
392 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
393 char *p;
394 if (cmd_p->error_string)
395 continue;
396 p = xmalloc(strlen(cmd_p->ref_name) + 1);
397 strcpy(p, cmd_p->ref_name);
398 argv[argc] = p;
399 argc++;
400 }
401 argv[argc] = NULL;
402 status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
403 | RUN_COMMAND_STDOUT_TO_STDERR);
404 run_status(status, update_post_hook);
405}
406
407static void execute_commands(const char *unpacker_error)
408{
409 struct command *cmd = commands;
410 unsigned char sha1[20];
411
412 if (unpacker_error) {
413 while (cmd) {
414 cmd->error_string = "n/a (unpacker error)";
415 cmd = cmd->next;
416 }
417 return;
418 }
419
420 if (run_receive_hook(pre_receive_hook)) {
421 while (cmd) {
422 cmd->error_string = "pre-receive hook declined";
423 cmd = cmd->next;
424 }
425 return;
426 }
427
428 head_name = resolve_ref("HEAD", sha1, 0, NULL);
429
430 while (cmd) {
431 cmd->error_string = update(cmd);
432 cmd = cmd->next;
433 }
434}
435
436static void read_head_info(void)
437{
438 struct command **p = &commands;
439 for (;;) {
440 static char line[1000];
441 unsigned char old_sha1[20], new_sha1[20];
442 struct command *cmd;
443 char *refname;
444 int len, reflen;
445
446 len = packet_read_line(0, line, sizeof(line));
447 if (!len)
448 break;
449 if (line[len-1] == '\n')
450 line[--len] = 0;
451 if (len < 83 ||
452 line[40] != ' ' ||
453 line[81] != ' ' ||
454 get_sha1_hex(line, old_sha1) ||
455 get_sha1_hex(line + 41, new_sha1))
456 die("protocol error: expected old/new/ref, got '%s'",
457 line);
458
459 refname = line + 82;
460 reflen = strlen(refname);
461 if (reflen + 82 < len) {
462 if (strstr(refname + reflen + 1, "report-status"))
463 report_status = 1;
464 }
465 cmd = xmalloc(sizeof(struct command) + len - 80);
466 hashcpy(cmd->old_sha1, old_sha1);
467 hashcpy(cmd->new_sha1, new_sha1);
468 memcpy(cmd->ref_name, line + 82, len - 81);
469 cmd->error_string = NULL;
470 cmd->next = NULL;
471 *p = cmd;
472 p = &cmd->next;
473 }
474}
475
476static const char *parse_pack_header(struct pack_header *hdr)
477{
478 switch (read_pack_header(0, hdr)) {
479 case PH_ERROR_EOF:
480 return "eof before pack header was fully read";
481
482 case PH_ERROR_PACK_SIGNATURE:
483 return "protocol error (pack signature mismatch detected)";
484
485 case PH_ERROR_PROTOCOL:
486 return "protocol error (pack version unsupported)";
487
488 default:
489 return "unknown error in parse_pack_header";
490
491 case 0:
492 return NULL;
493 }
494}
495
496static const char *pack_lockfile;
497
498static const char *unpack(void)
499{
500 struct pack_header hdr;
501 const char *hdr_err;
502 char hdr_arg[38];
503
504 hdr_err = parse_pack_header(&hdr);
505 if (hdr_err)
506 return hdr_err;
507 snprintf(hdr_arg, sizeof(hdr_arg),
508 "--pack_header=%"PRIu32",%"PRIu32,
509 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
510
511 if (ntohl(hdr.hdr_entries) < unpack_limit) {
512 int code, i = 0;
513 const char *unpacker[4];
514 unpacker[i++] = "unpack-objects";
515 if (receive_fsck_objects)
516 unpacker[i++] = "--strict";
517 unpacker[i++] = hdr_arg;
518 unpacker[i++] = NULL;
519 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
520 if (!code)
521 return NULL;
522 run_status(code, unpacker[0]);
523 return "unpack-objects abnormal exit";
524 } else {
525 const char *keeper[7];
526 int s, status, i = 0;
527 char keep_arg[256];
528 struct child_process ip;
529
530 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
531 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
532 strcpy(keep_arg + s, "localhost");
533
534 keeper[i++] = "index-pack";
535 keeper[i++] = "--stdin";
536 if (receive_fsck_objects)
537 keeper[i++] = "--strict";
538 keeper[i++] = "--fix-thin";
539 keeper[i++] = hdr_arg;
540 keeper[i++] = keep_arg;
541 keeper[i++] = NULL;
542 memset(&ip, 0, sizeof(ip));
543 ip.argv = keeper;
544 ip.out = -1;
545 ip.git_cmd = 1;
546 status = start_command(&ip);
547 if (status) {
548 run_status(status, keeper[0]);
549 return "index-pack fork failed";
550 }
551 pack_lockfile = index_pack_lockfile(ip.out);
552 close(ip.out);
553 status = finish_command(&ip);
554 if (!status) {
555 reprepare_packed_git();
556 return NULL;
557 }
558 run_status(status, keeper[0]);
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 }
688 return 0;
689}