use uppercase POSIX compliant signals for the 'trap' command
[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"
11
12 static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
13
14 enum deny_action {
15         DENY_IGNORE,
16         DENY_WARN,
17         DENY_REFUSE,
18 };
19
20 static int deny_deletes = 0;
21 static int deny_non_fast_forwards = 0;
22 static enum deny_action deny_current_branch = DENY_WARN;
23 static int receive_fsck_objects;
24 static int receive_unpack_limit = -1;
25 static int transfer_unpack_limit = -1;
26 static int unpack_limit = 100;
27 static int report_status;
28
29 static char capabilities[] = " report-status delete-refs ";
30 static int capabilities_sent;
31
32 static enum deny_action parse_deny_action(const char *var, const char *value)
33 {
34         if (value) {
35                 if (!strcasecmp(value, "ignore"))
36                         return DENY_IGNORE;
37                 if (!strcasecmp(value, "warn"))
38                         return DENY_WARN;
39                 if (!strcasecmp(value, "refuse"))
40                         return DENY_REFUSE;
41         }
42         if (git_config_bool(var, value))
43                 return DENY_REFUSE;
44         return DENY_IGNORE;
45 }
46
47 static int receive_pack_config(const char *var, const char *value, void *cb)
48 {
49         if (strcmp(var, "receive.denydeletes") == 0) {
50                 deny_deletes = git_config_bool(var, value);
51                 return 0;
52         }
53
54         if (strcmp(var, "receive.denynonfastforwards") == 0) {
55                 deny_non_fast_forwards = git_config_bool(var, value);
56                 return 0;
57         }
58
59         if (strcmp(var, "receive.unpacklimit") == 0) {
60                 receive_unpack_limit = git_config_int(var, value);
61                 return 0;
62         }
63
64         if (strcmp(var, "transfer.unpacklimit") == 0) {
65                 transfer_unpack_limit = git_config_int(var, value);
66                 return 0;
67         }
68
69         if (strcmp(var, "receive.fsckobjects") == 0) {
70                 receive_fsck_objects = git_config_bool(var, value);
71                 return 0;
72         }
73
74         if (!strcmp(var, "receive.denycurrentbranch")) {
75                 deny_current_branch = parse_deny_action(var, value);
76                 return 0;
77         }
78
79         return git_default_config(var, value, cb);
80 }
81
82 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
83 {
84         if (capabilities_sent)
85                 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
86         else
87                 packet_write(1, "%s %s%c%s\n",
88                              sha1_to_hex(sha1), path, 0, capabilities);
89         capabilities_sent = 1;
90         return 0;
91 }
92
93 static void write_head_info(void)
94 {
95         for_each_ref(show_ref, NULL);
96         if (!capabilities_sent)
97                 show_ref("capabilities^{}", null_sha1, 0, NULL);
98
99 }
100
101 struct command {
102         struct command *next;
103         const char *error_string;
104         unsigned char old_sha1[20];
105         unsigned char new_sha1[20];
106         char ref_name[FLEX_ARRAY]; /* more */
107 };
108
109 static struct command *commands;
110
111 static const char pre_receive_hook[] = "hooks/pre-receive";
112 static const char post_receive_hook[] = "hooks/post-receive";
113
114 static int hook_status(int code, const char *hook_name)
115 {
116         switch (code) {
117         case 0:
118                 return 0;
119         case -ERR_RUN_COMMAND_FORK:
120                 return error("hook fork failed");
121         case -ERR_RUN_COMMAND_EXEC:
122                 return error("hook execute failed");
123         case -ERR_RUN_COMMAND_PIPE:
124                 return error("hook pipe failed");
125         case -ERR_RUN_COMMAND_WAITPID:
126                 return error("waitpid failed");
127         case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
128                 return error("waitpid is confused");
129         case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
130                 return error("%s died of signal", hook_name);
131         case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
132                 return error("%s died strangely", hook_name);
133         default:
134                 error("%s exited with error code %d", hook_name, -code);
135                 return -code;
136         }
137 }
138
139 static int run_hook(const char *hook_name)
140 {
141         static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
142         struct command *cmd;
143         struct child_process proc;
144         const char *argv[2];
145         int have_input = 0, code;
146
147         for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
148                 if (!cmd->error_string)
149                         have_input = 1;
150         }
151
152         if (!have_input || access(hook_name, X_OK) < 0)
153                 return 0;
154
155         argv[0] = hook_name;
156         argv[1] = NULL;
157
158         memset(&proc, 0, sizeof(proc));
159         proc.argv = argv;
160         proc.in = -1;
161         proc.stdout_to_stderr = 1;
162
163         code = start_command(&proc);
164         if (code)
165                 return hook_status(code, hook_name);
166         for (cmd = commands; cmd; cmd = cmd->next) {
167                 if (!cmd->error_string) {
168                         size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
169                                 sha1_to_hex(cmd->old_sha1),
170                                 sha1_to_hex(cmd->new_sha1),
171                                 cmd->ref_name);
172                         if (write_in_full(proc.in, buf, n) != n)
173                                 break;
174                 }
175         }
176         close(proc.in);
177         return hook_status(finish_command(&proc), hook_name);
178 }
179
180 static int run_update_hook(struct command *cmd)
181 {
182         static const char update_hook[] = "hooks/update";
183         struct child_process proc;
184         const char *argv[5];
185
186         if (access(update_hook, X_OK) < 0)
187                 return 0;
188
189         argv[0] = update_hook;
190         argv[1] = cmd->ref_name;
191         argv[2] = sha1_to_hex(cmd->old_sha1);
192         argv[3] = sha1_to_hex(cmd->new_sha1);
193         argv[4] = NULL;
194
195         memset(&proc, 0, sizeof(proc));
196         proc.argv = argv;
197         proc.no_stdin = 1;
198         proc.stdout_to_stderr = 1;
199
200         return hook_status(run_command(&proc), update_hook);
201 }
202
203 static int is_ref_checked_out(const char *ref)
204 {
205         unsigned char sha1[20];
206         const char *head;
207
208         if (is_bare_repository())
209                 return 0;
210
211         head = resolve_ref("HEAD", sha1, 0, NULL);
212         if (!head)
213                 return 0;
214         return !strcmp(head, ref);
215 }
216
217 static const char *update(struct command *cmd)
218 {
219         const char *name = cmd->ref_name;
220         unsigned char *old_sha1 = cmd->old_sha1;
221         unsigned char *new_sha1 = cmd->new_sha1;
222         struct ref_lock *lock;
223
224         /* only refs/... are allowed */
225         if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
226                 error("refusing to create funny ref '%s' remotely", name);
227                 return "funny refname";
228         }
229
230         switch (deny_current_branch) {
231         case DENY_IGNORE:
232                 break;
233         case DENY_WARN:
234                 if (!is_ref_checked_out(name))
235                         break;
236                 warning("updating the currently checked out branch; this may"
237                         " cause confusion,\n"
238                         "as the index and working tree do not reflect changes"
239                         " that are now in HEAD.");
240                 break;
241         case DENY_REFUSE:
242                 if (!is_ref_checked_out(name))
243                         break;
244                 error("refusing to update checked out branch: %s", name);
245                 return "branch is currently checked out";
246         }
247
248         if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
249                 error("unpack should have generated %s, "
250                       "but I can't find it!", sha1_to_hex(new_sha1));
251                 return "bad pack";
252         }
253         if (deny_deletes && is_null_sha1(new_sha1) &&
254             !is_null_sha1(old_sha1) &&
255             !prefixcmp(name, "refs/heads/")) {
256                 error("denying ref deletion for %s", name);
257                 return "deletion prohibited";
258         }
259         if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
260             !is_null_sha1(old_sha1) &&
261             !prefixcmp(name, "refs/heads/")) {
262                 struct object *old_object, *new_object;
263                 struct commit *old_commit, *new_commit;
264                 struct commit_list *bases, *ent;
265
266                 old_object = parse_object(old_sha1);
267                 new_object = parse_object(new_sha1);
268
269                 if (!old_object || !new_object ||
270                     old_object->type != OBJ_COMMIT ||
271                     new_object->type != OBJ_COMMIT) {
272                         error("bad sha1 objects for %s", name);
273                         return "bad ref";
274                 }
275                 old_commit = (struct commit *)old_object;
276                 new_commit = (struct commit *)new_object;
277                 bases = get_merge_bases(old_commit, new_commit, 1);
278                 for (ent = bases; ent; ent = ent->next)
279                         if (!hashcmp(old_sha1, ent->item->object.sha1))
280                                 break;
281                 free_commit_list(bases);
282                 if (!ent) {
283                         error("denying non-fast forward %s"
284                               " (you should pull first)", name);
285                         return "non-fast forward";
286                 }
287         }
288         if (run_update_hook(cmd)) {
289                 error("hook declined to update %s", name);
290                 return "hook declined";
291         }
292
293         if (is_null_sha1(new_sha1)) {
294                 if (!parse_object(old_sha1)) {
295                         warning ("Allowing deletion of corrupt ref.");
296                         old_sha1 = NULL;
297                 }
298                 if (delete_ref(name, old_sha1, 0)) {
299                         error("failed to delete %s", name);
300                         return "failed to delete";
301                 }
302                 return NULL; /* good */
303         }
304         else {
305                 lock = lock_any_ref_for_update(name, old_sha1, 0);
306                 if (!lock) {
307                         error("failed to lock %s", name);
308                         return "failed to lock";
309                 }
310                 if (write_ref_sha1(lock, new_sha1, "push")) {
311                         return "failed to write"; /* error() already called */
312                 }
313                 return NULL; /* good */
314         }
315 }
316
317 static char update_post_hook[] = "hooks/post-update";
318
319 static void run_update_post_hook(struct command *cmd)
320 {
321         struct command *cmd_p;
322         int argc;
323         const char **argv;
324
325         for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
326                 if (cmd_p->error_string)
327                         continue;
328                 argc++;
329         }
330         if (!argc || access(update_post_hook, X_OK) < 0)
331                 return;
332         argv = xmalloc(sizeof(*argv) * (2 + argc));
333         argv[0] = update_post_hook;
334
335         for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
336                 char *p;
337                 if (cmd_p->error_string)
338                         continue;
339                 p = xmalloc(strlen(cmd_p->ref_name) + 1);
340                 strcpy(p, cmd_p->ref_name);
341                 argv[argc] = p;
342                 argc++;
343         }
344         argv[argc] = NULL;
345         run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
346                 | RUN_COMMAND_STDOUT_TO_STDERR);
347 }
348
349 static void execute_commands(const char *unpacker_error)
350 {
351         struct command *cmd = commands;
352
353         if (unpacker_error) {
354                 while (cmd) {
355                         cmd->error_string = "n/a (unpacker error)";
356                         cmd = cmd->next;
357                 }
358                 return;
359         }
360
361         if (run_hook(pre_receive_hook)) {
362                 while (cmd) {
363                         cmd->error_string = "pre-receive hook declined";
364                         cmd = cmd->next;
365                 }
366                 return;
367         }
368
369         while (cmd) {
370                 cmd->error_string = update(cmd);
371                 cmd = cmd->next;
372         }
373 }
374
375 static void read_head_info(void)
376 {
377         struct command **p = &commands;
378         for (;;) {
379                 static char line[1000];
380                 unsigned char old_sha1[20], new_sha1[20];
381                 struct command *cmd;
382                 char *refname;
383                 int len, reflen;
384
385                 len = packet_read_line(0, line, sizeof(line));
386                 if (!len)
387                         break;
388                 if (line[len-1] == '\n')
389                         line[--len] = 0;
390                 if (len < 83 ||
391                     line[40] != ' ' ||
392                     line[81] != ' ' ||
393                     get_sha1_hex(line, old_sha1) ||
394                     get_sha1_hex(line + 41, new_sha1))
395                         die("protocol error: expected old/new/ref, got '%s'",
396                             line);
397
398                 refname = line + 82;
399                 reflen = strlen(refname);
400                 if (reflen + 82 < len) {
401                         if (strstr(refname + reflen + 1, "report-status"))
402                                 report_status = 1;
403                 }
404                 cmd = xmalloc(sizeof(struct command) + len - 80);
405                 hashcpy(cmd->old_sha1, old_sha1);
406                 hashcpy(cmd->new_sha1, new_sha1);
407                 memcpy(cmd->ref_name, line + 82, len - 81);
408                 cmd->error_string = NULL;
409                 cmd->next = NULL;
410                 *p = cmd;
411                 p = &cmd->next;
412         }
413 }
414
415 static const char *parse_pack_header(struct pack_header *hdr)
416 {
417         switch (read_pack_header(0, hdr)) {
418         case PH_ERROR_EOF:
419                 return "eof before pack header was fully read";
420
421         case PH_ERROR_PACK_SIGNATURE:
422                 return "protocol error (pack signature mismatch detected)";
423
424         case PH_ERROR_PROTOCOL:
425                 return "protocol error (pack version unsupported)";
426
427         default:
428                 return "unknown error in parse_pack_header";
429
430         case 0:
431                 return NULL;
432         }
433 }
434
435 static const char *pack_lockfile;
436
437 static const char *unpack(void)
438 {
439         struct pack_header hdr;
440         const char *hdr_err;
441         char hdr_arg[38];
442
443         hdr_err = parse_pack_header(&hdr);
444         if (hdr_err)
445                 return hdr_err;
446         snprintf(hdr_arg, sizeof(hdr_arg),
447                         "--pack_header=%"PRIu32",%"PRIu32,
448                         ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
449
450         if (ntohl(hdr.hdr_entries) < unpack_limit) {
451                 int code, i = 0;
452                 const char *unpacker[4];
453                 unpacker[i++] = "unpack-objects";
454                 if (receive_fsck_objects)
455                         unpacker[i++] = "--strict";
456                 unpacker[i++] = hdr_arg;
457                 unpacker[i++] = NULL;
458                 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
459                 switch (code) {
460                 case 0:
461                         return NULL;
462                 case -ERR_RUN_COMMAND_FORK:
463                         return "unpack fork failed";
464                 case -ERR_RUN_COMMAND_EXEC:
465                         return "unpack execute failed";
466                 case -ERR_RUN_COMMAND_WAITPID:
467                         return "waitpid failed";
468                 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
469                         return "waitpid is confused";
470                 case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
471                         return "unpacker died of signal";
472                 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
473                         return "unpacker died strangely";
474                 default:
475                         return "unpacker exited with error code";
476                 }
477         } else {
478                 const char *keeper[7];
479                 int s, status, i = 0;
480                 char keep_arg[256];
481                 struct child_process ip;
482
483                 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
484                 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
485                         strcpy(keep_arg + s, "localhost");
486
487                 keeper[i++] = "index-pack";
488                 keeper[i++] = "--stdin";
489                 if (receive_fsck_objects)
490                         keeper[i++] = "--strict";
491                 keeper[i++] = "--fix-thin";
492                 keeper[i++] = hdr_arg;
493                 keeper[i++] = keep_arg;
494                 keeper[i++] = NULL;
495                 memset(&ip, 0, sizeof(ip));
496                 ip.argv = keeper;
497                 ip.out = -1;
498                 ip.git_cmd = 1;
499                 if (start_command(&ip))
500                         return "index-pack fork failed";
501                 pack_lockfile = index_pack_lockfile(ip.out);
502                 close(ip.out);
503                 status = finish_command(&ip);
504                 if (!status) {
505                         reprepare_packed_git();
506                         return NULL;
507                 }
508                 return "index-pack abnormal exit";
509         }
510 }
511
512 static void report(const char *unpack_status)
513 {
514         struct command *cmd;
515         packet_write(1, "unpack %s\n",
516                      unpack_status ? unpack_status : "ok");
517         for (cmd = commands; cmd; cmd = cmd->next) {
518                 if (!cmd->error_string)
519                         packet_write(1, "ok %s\n",
520                                      cmd->ref_name);
521                 else
522                         packet_write(1, "ng %s %s\n",
523                                      cmd->ref_name, cmd->error_string);
524         }
525         packet_flush(1);
526 }
527
528 static int delete_only(struct command *cmd)
529 {
530         while (cmd) {
531                 if (!is_null_sha1(cmd->new_sha1))
532                         return 0;
533                 cmd = cmd->next;
534         }
535         return 1;
536 }
537
538 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
539 {
540         char *other;
541         size_t len;
542         struct remote *remote;
543         struct transport *transport;
544         const struct ref *extra;
545
546         e->name[-1] = '\0';
547         other = xstrdup(make_absolute_path(e->base));
548         e->name[-1] = '/';
549         len = strlen(other);
550
551         while (other[len-1] == '/')
552                 other[--len] = '\0';
553         if (len < 8 || memcmp(other + len - 8, "/objects", 8))
554                 return 0;
555         /* Is this a git repository with refs? */
556         memcpy(other + len - 8, "/refs", 6);
557         if (!is_directory(other))
558                 return 0;
559         other[len - 8] = '\0';
560         remote = remote_get(other);
561         transport = transport_get(remote, other);
562         for (extra = transport_get_remote_refs(transport);
563              extra;
564              extra = extra->next) {
565                 add_extra_ref(".have", extra->old_sha1, 0);
566         }
567         transport_disconnect(transport);
568         free(other);
569         return 0;
570 }
571
572 static void add_alternate_refs(void)
573 {
574         foreach_alt_odb(add_refs_from_alternate, NULL);
575 }
576
577 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
578 {
579         int i;
580         char *dir = NULL;
581
582         argv++;
583         for (i = 1; i < argc; i++) {
584                 const char *arg = *argv++;
585
586                 if (*arg == '-') {
587                         /* Do flag handling here */
588                         usage(receive_pack_usage);
589                 }
590                 if (dir)
591                         usage(receive_pack_usage);
592                 dir = xstrdup(arg);
593         }
594         if (!dir)
595                 usage(receive_pack_usage);
596
597         setup_path();
598
599         if (!enter_repo(dir, 0))
600                 die("'%s': unable to chdir or not a git archive", dir);
601
602         if (is_repository_shallow())
603                 die("attempt to push into a shallow repository");
604
605         git_config(receive_pack_config, NULL);
606
607         if (0 <= transfer_unpack_limit)
608                 unpack_limit = transfer_unpack_limit;
609         else if (0 <= receive_unpack_limit)
610                 unpack_limit = receive_unpack_limit;
611
612         add_alternate_refs();
613         write_head_info();
614         clear_extra_refs();
615
616         /* EOF */
617         packet_flush(1);
618
619         read_head_info();
620         if (commands) {
621                 const char *unpack_status = NULL;
622
623                 if (!delete_only(commands))
624                         unpack_status = unpack();
625                 execute_commands(unpack_status);
626                 if (pack_lockfile)
627                         unlink(pack_lockfile);
628                 if (report_status)
629                         report(unpack_status);
630                 run_hook(post_receive_hook);
631                 run_update_post_hook(commands);
632         }
633         return 0;
634 }