Code

run_command: report system call errors instead of returning error codes
[git.git] / builtin-receive-pack.c
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,
19 };
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 const char *head_name;
32 static char *capabilities_to_send;
34 static 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 }
49 static 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         }
56         if (strcmp(var, "receive.denynonfastforwards") == 0) {
57                 deny_non_fast_forwards = git_config_bool(var, value);
58                 return 0;
59         }
61         if (strcmp(var, "receive.unpacklimit") == 0) {
62                 receive_unpack_limit = git_config_int(var, value);
63                 return 0;
64         }
66         if (strcmp(var, "transfer.unpacklimit") == 0) {
67                 transfer_unpack_limit = git_config_int(var, value);
68                 return 0;
69         }
71         if (strcmp(var, "receive.fsckobjects") == 0) {
72                 receive_fsck_objects = git_config_bool(var, value);
73                 return 0;
74         }
76         if (!strcmp(var, "receive.denycurrentbranch")) {
77                 deny_current_branch = parse_deny_action(var, value);
78                 return 0;
79         }
81         if (strcmp(var, "receive.denydeletecurrent") == 0) {
82                 deny_delete_current = parse_deny_action(var, value);
83                 return 0;
84         }
86         if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
87                 prefer_ofs_delta = git_config_bool(var, value);
88                 return 0;
89         }
91         return git_default_config(var, value, cb);
92 }
94 static 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;
105 static void write_head_info(void)
107         for_each_ref(show_ref, NULL);
108         if (capabilities_to_send)
109                 show_ref("capabilities^{}", null_sha1, 0, NULL);
113 struct 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 };
121 static struct command *commands;
123 static const char pre_receive_hook[] = "hooks/pre-receive";
124 static const char post_receive_hook[] = "hooks/post-receive";
126 static int run_status(int code, const char *cmd_name)
128         if (code < 0 && errno == ENOENT)
129                 return error("execute of %s failed", cmd_name);
130         else if (code > 0)
131                 error("%s exited with error code %d", cmd_name, code);
132         return code;
135 static int run_receive_hook(const char *hook_name)
137         static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
138         struct command *cmd;
139         struct child_process proc;
140         const char *argv[2];
141         int have_input = 0, code;
143         for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
144                 if (!cmd->error_string)
145                         have_input = 1;
146         }
148         if (!have_input || access(hook_name, X_OK) < 0)
149                 return 0;
151         argv[0] = hook_name;
152         argv[1] = NULL;
154         memset(&proc, 0, sizeof(proc));
155         proc.argv = argv;
156         proc.in = -1;
157         proc.stdout_to_stderr = 1;
159         code = start_command(&proc);
160         if (code)
161                 return run_status(code, hook_name);
162         for (cmd = commands; cmd; cmd = cmd->next) {
163                 if (!cmd->error_string) {
164                         size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
165                                 sha1_to_hex(cmd->old_sha1),
166                                 sha1_to_hex(cmd->new_sha1),
167                                 cmd->ref_name);
168                         if (write_in_full(proc.in, buf, n) != n)
169                                 break;
170                 }
171         }
172         close(proc.in);
173         return run_status(finish_command(&proc), hook_name);
176 static int run_update_hook(struct command *cmd)
178         static const char update_hook[] = "hooks/update";
179         const char *argv[5];
181         if (access(update_hook, X_OK) < 0)
182                 return 0;
184         argv[0] = update_hook;
185         argv[1] = cmd->ref_name;
186         argv[2] = sha1_to_hex(cmd->old_sha1);
187         argv[3] = sha1_to_hex(cmd->new_sha1);
188         argv[4] = NULL;
190         return run_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
191                                         RUN_COMMAND_STDOUT_TO_STDERR),
192                         update_hook);
195 static int is_ref_checked_out(const char *ref)
197         if (is_bare_repository())
198                 return 0;
200         if (!head_name)
201                 return 0;
202         return !strcmp(head_name, ref);
205 static char *warn_unconfigured_deny_msg[] = {
206         "Updating the currently checked out branch may cause confusion,",
207         "as the index and work tree do not reflect changes that are in HEAD.",
208         "As a result, you may see the changes you just pushed into it",
209         "reverted when you run 'git diff' over there, and you may want",
210         "to run 'git reset --hard' before starting to work to recover.",
211         "",
212         "You can set 'receive.denyCurrentBranch' configuration variable to",
213         "'refuse' in the remote repository to forbid pushing into its",
214         "current branch."
215         "",
216         "To allow pushing into the current branch, you can set it to 'ignore';",
217         "but this is not recommended unless you arranged to update its work",
218         "tree to match what you pushed in some other way.",
219         "",
220         "To squelch this message, you can set it to 'warn'.",
221         "",
222         "Note that the default will change in a future version of git",
223         "to refuse updating the current branch unless you have the",
224         "configuration variable set to either 'ignore' or 'warn'."
225 };
227 static void warn_unconfigured_deny(void)
229         int i;
230         for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
231                 warning("%s", warn_unconfigured_deny_msg[i]);
234 static char *warn_unconfigured_deny_delete_current_msg[] = {
235         "Deleting the current branch can cause confusion by making the next",
236         "'git clone' not check out any file.",
237         "",
238         "You can set 'receive.denyDeleteCurrent' configuration variable to",
239         "'refuse' in the remote repository to disallow deleting the current",
240         "branch.",
241         "",
242         "You can set it to 'ignore' to allow such a delete without a warning.",
243         "",
244         "To make this warning message less loud, you can set it to 'warn'.",
245         "",
246         "Note that the default will change in a future version of git",
247         "to refuse deleting the current branch unless you have the",
248         "configuration variable set to either 'ignore' or 'warn'."
249 };
251 static void warn_unconfigured_deny_delete_current(void)
253         int i;
254         for (i = 0;
255              i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
256              i++)
257                 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
260 static const char *update(struct command *cmd)
262         const char *name = cmd->ref_name;
263         unsigned char *old_sha1 = cmd->old_sha1;
264         unsigned char *new_sha1 = cmd->new_sha1;
265         struct ref_lock *lock;
267         /* only refs/... are allowed */
268         if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
269                 error("refusing to create funny ref '%s' remotely", name);
270                 return "funny refname";
271         }
273         if (is_ref_checked_out(name)) {
274                 switch (deny_current_branch) {
275                 case DENY_IGNORE:
276                         break;
277                 case DENY_UNCONFIGURED:
278                 case DENY_WARN:
279                         warning("updating the current branch");
280                         if (deny_current_branch == DENY_UNCONFIGURED)
281                                 warn_unconfigured_deny();
282                         break;
283                 case DENY_REFUSE:
284                         error("refusing to update checked out branch: %s", name);
285                         return "branch is currently checked out";
286                 }
287         }
289         if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
290                 error("unpack should have generated %s, "
291                       "but I can't find it!", sha1_to_hex(new_sha1));
292                 return "bad pack";
293         }
295         if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
296                 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
297                         error("denying ref deletion for %s", name);
298                         return "deletion prohibited";
299                 }
301                 if (!strcmp(name, head_name)) {
302                         switch (deny_delete_current) {
303                         case DENY_IGNORE:
304                                 break;
305                         case DENY_WARN:
306                         case DENY_UNCONFIGURED:
307                                 if (deny_delete_current == DENY_UNCONFIGURED)
308                                         warn_unconfigured_deny_delete_current();
309                                 warning("deleting the current branch");
310                                 break;
311                         case DENY_REFUSE:
312                                 error("refusing to delete the current branch: %s", name);
313                                 return "deletion of the current branch prohibited";
314                         }
315                 }
316         }
318         if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
319             !is_null_sha1(old_sha1) &&
320             !prefixcmp(name, "refs/heads/")) {
321                 struct object *old_object, *new_object;
322                 struct commit *old_commit, *new_commit;
323                 struct commit_list *bases, *ent;
325                 old_object = parse_object(old_sha1);
326                 new_object = parse_object(new_sha1);
328                 if (!old_object || !new_object ||
329                     old_object->type != OBJ_COMMIT ||
330                     new_object->type != OBJ_COMMIT) {
331                         error("bad sha1 objects for %s", name);
332                         return "bad ref";
333                 }
334                 old_commit = (struct commit *)old_object;
335                 new_commit = (struct commit *)new_object;
336                 bases = get_merge_bases(old_commit, new_commit, 1);
337                 for (ent = bases; ent; ent = ent->next)
338                         if (!hashcmp(old_sha1, ent->item->object.sha1))
339                                 break;
340                 free_commit_list(bases);
341                 if (!ent) {
342                         error("denying non-fast forward %s"
343                               " (you should pull first)", name);
344                         return "non-fast forward";
345                 }
346         }
347         if (run_update_hook(cmd)) {
348                 error("hook declined to update %s", name);
349                 return "hook declined";
350         }
352         if (is_null_sha1(new_sha1)) {
353                 if (!parse_object(old_sha1)) {
354                         warning ("Allowing deletion of corrupt ref.");
355                         old_sha1 = NULL;
356                 }
357                 if (delete_ref(name, old_sha1, 0)) {
358                         error("failed to delete %s", name);
359                         return "failed to delete";
360                 }
361                 return NULL; /* good */
362         }
363         else {
364                 lock = lock_any_ref_for_update(name, old_sha1, 0);
365                 if (!lock) {
366                         error("failed to lock %s", name);
367                         return "failed to lock";
368                 }
369                 if (write_ref_sha1(lock, new_sha1, "push")) {
370                         return "failed to write"; /* error() already called */
371                 }
372                 return NULL; /* good */
373         }
376 static char update_post_hook[] = "hooks/post-update";
378 static void run_update_post_hook(struct command *cmd)
380         struct command *cmd_p;
381         int argc, status;
382         const char **argv;
384         for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
385                 if (cmd_p->error_string)
386                         continue;
387                 argc++;
388         }
389         if (!argc || access(update_post_hook, X_OK) < 0)
390                 return;
391         argv = xmalloc(sizeof(*argv) * (2 + argc));
392         argv[0] = update_post_hook;
394         for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
395                 char *p;
396                 if (cmd_p->error_string)
397                         continue;
398                 p = xmalloc(strlen(cmd_p->ref_name) + 1);
399                 strcpy(p, cmd_p->ref_name);
400                 argv[argc] = p;
401                 argc++;
402         }
403         argv[argc] = NULL;
404         status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
405                         | RUN_COMMAND_STDOUT_TO_STDERR);
406         run_status(status, update_post_hook);
409 static void execute_commands(const char *unpacker_error)
411         struct command *cmd = commands;
412         unsigned char sha1[20];
414         if (unpacker_error) {
415                 while (cmd) {
416                         cmd->error_string = "n/a (unpacker error)";
417                         cmd = cmd->next;
418                 }
419                 return;
420         }
422         if (run_receive_hook(pre_receive_hook)) {
423                 while (cmd) {
424                         cmd->error_string = "pre-receive hook declined";
425                         cmd = cmd->next;
426                 }
427                 return;
428         }
430         head_name = resolve_ref("HEAD", sha1, 0, NULL);
432         while (cmd) {
433                 cmd->error_string = update(cmd);
434                 cmd = cmd->next;
435         }
438 static void read_head_info(void)
440         struct command **p = &commands;
441         for (;;) {
442                 static char line[1000];
443                 unsigned char old_sha1[20], new_sha1[20];
444                 struct command *cmd;
445                 char *refname;
446                 int len, reflen;
448                 len = packet_read_line(0, line, sizeof(line));
449                 if (!len)
450                         break;
451                 if (line[len-1] == '\n')
452                         line[--len] = 0;
453                 if (len < 83 ||
454                     line[40] != ' ' ||
455                     line[81] != ' ' ||
456                     get_sha1_hex(line, old_sha1) ||
457                     get_sha1_hex(line + 41, new_sha1))
458                         die("protocol error: expected old/new/ref, got '%s'",
459                             line);
461                 refname = line + 82;
462                 reflen = strlen(refname);
463                 if (reflen + 82 < len) {
464                         if (strstr(refname + reflen + 1, "report-status"))
465                                 report_status = 1;
466                 }
467                 cmd = xmalloc(sizeof(struct command) + len - 80);
468                 hashcpy(cmd->old_sha1, old_sha1);
469                 hashcpy(cmd->new_sha1, new_sha1);
470                 memcpy(cmd->ref_name, line + 82, len - 81);
471                 cmd->error_string = NULL;
472                 cmd->next = NULL;
473                 *p = cmd;
474                 p = &cmd->next;
475         }
478 static const char *parse_pack_header(struct pack_header *hdr)
480         switch (read_pack_header(0, hdr)) {
481         case PH_ERROR_EOF:
482                 return "eof before pack header was fully read";
484         case PH_ERROR_PACK_SIGNATURE:
485                 return "protocol error (pack signature mismatch detected)";
487         case PH_ERROR_PROTOCOL:
488                 return "protocol error (pack version unsupported)";
490         default:
491                 return "unknown error in parse_pack_header";
493         case 0:
494                 return NULL;
495         }
498 static const char *pack_lockfile;
500 static const char *unpack(void)
502         struct pack_header hdr;
503         const char *hdr_err;
504         char hdr_arg[38];
506         hdr_err = parse_pack_header(&hdr);
507         if (hdr_err)
508                 return hdr_err;
509         snprintf(hdr_arg, sizeof(hdr_arg),
510                         "--pack_header=%"PRIu32",%"PRIu32,
511                         ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
513         if (ntohl(hdr.hdr_entries) < unpack_limit) {
514                 int code, i = 0;
515                 const char *unpacker[4];
516                 unpacker[i++] = "unpack-objects";
517                 if (receive_fsck_objects)
518                         unpacker[i++] = "--strict";
519                 unpacker[i++] = hdr_arg;
520                 unpacker[i++] = NULL;
521                 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
522                 if (!code)
523                         return NULL;
524                 run_status(code, unpacker[0]);
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                         run_status(status, keeper[0]);
551                         return "index-pack fork failed";
552                 }
553                 pack_lockfile = index_pack_lockfile(ip.out);
554                 close(ip.out);
555                 status = finish_command(&ip);
556                 if (!status) {
557                         reprepare_packed_git();
558                         return NULL;
559                 }
560                 run_status(status, keeper[0]);
561                 return "index-pack abnormal exit";
562         }
565 static void report(const char *unpack_status)
567         struct command *cmd;
568         packet_write(1, "unpack %s\n",
569                      unpack_status ? unpack_status : "ok");
570         for (cmd = commands; cmd; cmd = cmd->next) {
571                 if (!cmd->error_string)
572                         packet_write(1, "ok %s\n",
573                                      cmd->ref_name);
574                 else
575                         packet_write(1, "ng %s %s\n",
576                                      cmd->ref_name, cmd->error_string);
577         }
578         packet_flush(1);
581 static int delete_only(struct command *cmd)
583         while (cmd) {
584                 if (!is_null_sha1(cmd->new_sha1))
585                         return 0;
586                 cmd = cmd->next;
587         }
588         return 1;
591 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
593         char *other;
594         size_t len;
595         struct remote *remote;
596         struct transport *transport;
597         const struct ref *extra;
599         e->name[-1] = '\0';
600         other = xstrdup(make_absolute_path(e->base));
601         e->name[-1] = '/';
602         len = strlen(other);
604         while (other[len-1] == '/')
605                 other[--len] = '\0';
606         if (len < 8 || memcmp(other + len - 8, "/objects", 8))
607                 return 0;
608         /* Is this a git repository with refs? */
609         memcpy(other + len - 8, "/refs", 6);
610         if (!is_directory(other))
611                 return 0;
612         other[len - 8] = '\0';
613         remote = remote_get(other);
614         transport = transport_get(remote, other);
615         for (extra = transport_get_remote_refs(transport);
616              extra;
617              extra = extra->next) {
618                 add_extra_ref(".have", extra->old_sha1, 0);
619         }
620         transport_disconnect(transport);
621         free(other);
622         return 0;
625 static void add_alternate_refs(void)
627         foreach_alt_odb(add_refs_from_alternate, NULL);
630 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
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                         /* Do flag handling here */
641                         usage(receive_pack_usage);
642                 }
643                 if (dir)
644                         usage(receive_pack_usage);
645                 dir = xstrdup(arg);
646         }
647         if (!dir)
648                 usage(receive_pack_usage);
650         setup_path();
652         if (!enter_repo(dir, 0))
653                 die("'%s' does not appear to be a git repository", dir);
655         if (is_repository_shallow())
656                 die("attempt to push into a shallow repository");
658         git_config(receive_pack_config, NULL);
660         if (0 <= transfer_unpack_limit)
661                 unpack_limit = transfer_unpack_limit;
662         else if (0 <= receive_unpack_limit)
663                 unpack_limit = receive_unpack_limit;
665         capabilities_to_send = (prefer_ofs_delta) ?
666                 " report-status delete-refs ofs-delta " :
667                 " report-status delete-refs ";
669         add_alternate_refs();
670         write_head_info();
671         clear_extra_refs();
673         /* EOF */
674         packet_flush(1);
676         read_head_info();
677         if (commands) {
678                 const char *unpack_status = NULL;
680                 if (!delete_only(commands))
681                         unpack_status = unpack();
682                 execute_commands(unpack_status);
683                 if (pack_lockfile)
684                         unlink_or_warn(pack_lockfile);
685                 if (report_status)
686                         report(unpack_status);
687                 run_receive_hook(post_receive_hook);
688                 run_update_post_hook(commands);
689         }
690         return 0;