receive-pack: Refactor how capabilities are shown to the client
[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_UNCONFIGURED,
16         DENY_IGNORE,
17         DENY_WARN,
18         DENY_REFUSE,
19 };
20
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 int auto_update_server_info;
32 static int auto_gc = 1;
33 static const char *head_name;
34 static int sent_capabilities;
35
36 static enum deny_action parse_deny_action(const char *var, const char *value)
37 {
38         if (value) {
39                 if (!strcasecmp(value, "ignore"))
40                         return DENY_IGNORE;
41                 if (!strcasecmp(value, "warn"))
42                         return DENY_WARN;
43                 if (!strcasecmp(value, "refuse"))
44                         return DENY_REFUSE;
45         }
46         if (git_config_bool(var, value))
47                 return DENY_REFUSE;
48         return DENY_IGNORE;
49 }
50
51 static int receive_pack_config(const char *var, const char *value, void *cb)
52 {
53         if (strcmp(var, "receive.denydeletes") == 0) {
54                 deny_deletes = git_config_bool(var, value);
55                 return 0;
56         }
57
58         if (strcmp(var, "receive.denynonfastforwards") == 0) {
59                 deny_non_fast_forwards = git_config_bool(var, value);
60                 return 0;
61         }
62
63         if (strcmp(var, "receive.unpacklimit") == 0) {
64                 receive_unpack_limit = git_config_int(var, value);
65                 return 0;
66         }
67
68         if (strcmp(var, "transfer.unpacklimit") == 0) {
69                 transfer_unpack_limit = git_config_int(var, value);
70                 return 0;
71         }
72
73         if (strcmp(var, "receive.fsckobjects") == 0) {
74                 receive_fsck_objects = git_config_bool(var, value);
75                 return 0;
76         }
77
78         if (!strcmp(var, "receive.denycurrentbranch")) {
79                 deny_current_branch = parse_deny_action(var, value);
80                 return 0;
81         }
82
83         if (strcmp(var, "receive.denydeletecurrent") == 0) {
84                 deny_delete_current = parse_deny_action(var, value);
85                 return 0;
86         }
87
88         if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
89                 prefer_ofs_delta = git_config_bool(var, value);
90                 return 0;
91         }
92
93         if (strcmp(var, "receive.updateserverinfo") == 0) {
94                 auto_update_server_info = git_config_bool(var, value);
95                 return 0;
96         }
97
98         if (strcmp(var, "receive.autogc") == 0) {
99                 auto_gc = git_config_bool(var, value);
100                 return 0;
101         }
102
103         return git_default_config(var, value, cb);
104 }
105
106 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
107 {
108         if (sent_capabilities)
109                 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
110         else
111                 packet_write(1, "%s %s%c%s%s\n",
112                              sha1_to_hex(sha1), path, 0,
113                              " report-status delete-refs",
114                              prefer_ofs_delta ? " ofs-delta" : "");
115         sent_capabilities = 1;
116         return 0;
117 }
118
119 static void write_head_info(void)
120 {
121         for_each_ref(show_ref, NULL);
122         if (!sent_capabilities)
123                 show_ref("capabilities^{}", null_sha1, 0, NULL);
124
125 }
126
127 struct command {
128         struct command *next;
129         const char *error_string;
130         unsigned char old_sha1[20];
131         unsigned char new_sha1[20];
132         char ref_name[FLEX_ARRAY]; /* more */
133 };
134
135 static struct command *commands;
136
137 static const char pre_receive_hook[] = "hooks/pre-receive";
138 static const char post_receive_hook[] = "hooks/post-receive";
139
140 static 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 code;
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 finish_command(&proc);
179 }
180
181 static int run_update_hook(struct command *cmd)
182 {
183         static const char update_hook[] = "hooks/update";
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         return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
196                                         RUN_COMMAND_STDOUT_TO_STDERR);
197 }
198
199 static int is_ref_checked_out(const char *ref)
200 {
201         if (is_bare_repository())
202                 return 0;
203
204         if (!head_name)
205                 return 0;
206         return !strcmp(head_name, ref);
207 }
208
209 static char *warn_unconfigured_deny_msg[] = {
210         "Updating the currently checked out branch may cause confusion,",
211         "as the index and work tree do not reflect changes that are in HEAD.",
212         "As a result, you may see the changes you just pushed into it",
213         "reverted when you run 'git diff' over there, and you may want",
214         "to run 'git reset --hard' before starting to work to recover.",
215         "",
216         "You can set 'receive.denyCurrentBranch' configuration variable to",
217         "'refuse' in the remote repository to forbid pushing into its",
218         "current branch."
219         "",
220         "To allow pushing into the current branch, you can set it to 'ignore';",
221         "but this is not recommended unless you arranged to update its work",
222         "tree to match what you pushed in some other way.",
223         "",
224         "To squelch this message, you can set it to 'warn'.",
225         "",
226         "Note that the default will change in a future version of git",
227         "to refuse updating the current branch unless you have the",
228         "configuration variable set to either 'ignore' or 'warn'."
229 };
230
231 static void warn_unconfigured_deny(void)
232 {
233         int i;
234         for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
235                 warning("%s", warn_unconfigured_deny_msg[i]);
236 }
237
238 static char *warn_unconfigured_deny_delete_current_msg[] = {
239         "Deleting the current branch can cause confusion by making the next",
240         "'git clone' not check out any file.",
241         "",
242         "You can set 'receive.denyDeleteCurrent' configuration variable to",
243         "'refuse' in the remote repository to disallow deleting the current",
244         "branch.",
245         "",
246         "You can set it to 'ignore' to allow such a delete without a warning.",
247         "",
248         "To make this warning message less loud, you can set it to 'warn'.",
249         "",
250         "Note that the default will change in a future version of git",
251         "to refuse deleting the current branch unless you have the",
252         "configuration variable set to either 'ignore' or 'warn'."
253 };
254
255 static void warn_unconfigured_deny_delete_current(void)
256 {
257         int i;
258         for (i = 0;
259              i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
260              i++)
261                 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
262 }
263
264 static const char *update(struct command *cmd)
265 {
266         const char *name = cmd->ref_name;
267         unsigned char *old_sha1 = cmd->old_sha1;
268         unsigned char *new_sha1 = cmd->new_sha1;
269         struct ref_lock *lock;
270
271         /* only refs/... are allowed */
272         if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
273                 error("refusing to create funny ref '%s' remotely", name);
274                 return "funny refname";
275         }
276
277         if (is_ref_checked_out(name)) {
278                 switch (deny_current_branch) {
279                 case DENY_IGNORE:
280                         break;
281                 case DENY_UNCONFIGURED:
282                 case DENY_WARN:
283                         warning("updating the current branch");
284                         if (deny_current_branch == DENY_UNCONFIGURED)
285                                 warn_unconfigured_deny();
286                         break;
287                 case DENY_REFUSE:
288                         error("refusing to update checked out branch: %s", name);
289                         return "branch is currently checked out";
290                 }
291         }
292
293         if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
294                 error("unpack should have generated %s, "
295                       "but I can't find it!", sha1_to_hex(new_sha1));
296                 return "bad pack";
297         }
298
299         if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
300                 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
301                         error("denying ref deletion for %s", name);
302                         return "deletion prohibited";
303                 }
304
305                 if (!strcmp(name, head_name)) {
306                         switch (deny_delete_current) {
307                         case DENY_IGNORE:
308                                 break;
309                         case DENY_WARN:
310                         case DENY_UNCONFIGURED:
311                                 if (deny_delete_current == DENY_UNCONFIGURED)
312                                         warn_unconfigured_deny_delete_current();
313                                 warning("deleting the current branch");
314                                 break;
315                         case DENY_REFUSE:
316                                 error("refusing to delete the current branch: %s", name);
317                                 return "deletion of the current branch prohibited";
318                         }
319                 }
320         }
321
322         if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
323             !is_null_sha1(old_sha1) &&
324             !prefixcmp(name, "refs/heads/")) {
325                 struct object *old_object, *new_object;
326                 struct commit *old_commit, *new_commit;
327                 struct commit_list *bases, *ent;
328
329                 old_object = parse_object(old_sha1);
330                 new_object = parse_object(new_sha1);
331
332                 if (!old_object || !new_object ||
333                     old_object->type != OBJ_COMMIT ||
334                     new_object->type != OBJ_COMMIT) {
335                         error("bad sha1 objects for %s", name);
336                         return "bad ref";
337                 }
338                 old_commit = (struct commit *)old_object;
339                 new_commit = (struct commit *)new_object;
340                 bases = get_merge_bases(old_commit, new_commit, 1);
341                 for (ent = bases; ent; ent = ent->next)
342                         if (!hashcmp(old_sha1, ent->item->object.sha1))
343                                 break;
344                 free_commit_list(bases);
345                 if (!ent) {
346                         error("denying non-fast-forward %s"
347                               " (you should pull first)", name);
348                         return "non-fast-forward";
349                 }
350         }
351         if (run_update_hook(cmd)) {
352                 error("hook declined to update %s", name);
353                 return "hook declined";
354         }
355
356         if (is_null_sha1(new_sha1)) {
357                 if (!parse_object(old_sha1)) {
358                         warning ("Allowing deletion of corrupt ref.");
359                         old_sha1 = NULL;
360                 }
361                 if (delete_ref(name, old_sha1, 0)) {
362                         error("failed to delete %s", name);
363                         return "failed to delete";
364                 }
365                 return NULL; /* good */
366         }
367         else {
368                 lock = lock_any_ref_for_update(name, old_sha1, 0);
369                 if (!lock) {
370                         error("failed to lock %s", name);
371                         return "failed to lock";
372                 }
373                 if (write_ref_sha1(lock, new_sha1, "push")) {
374                         return "failed to write"; /* error() already called */
375                 }
376                 return NULL; /* good */
377         }
378 }
379
380 static char update_post_hook[] = "hooks/post-update";
381
382 static void run_update_post_hook(struct command *cmd)
383 {
384         struct command *cmd_p;
385         int argc, status;
386         const char **argv;
387
388         for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
389                 if (cmd_p->error_string)
390                         continue;
391                 argc++;
392         }
393         if (!argc || access(update_post_hook, X_OK) < 0)
394                 return;
395         argv = xmalloc(sizeof(*argv) * (2 + argc));
396         argv[0] = update_post_hook;
397
398         for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
399                 char *p;
400                 if (cmd_p->error_string)
401                         continue;
402                 p = xmalloc(strlen(cmd_p->ref_name) + 1);
403                 strcpy(p, cmd_p->ref_name);
404                 argv[argc] = p;
405                 argc++;
406         }
407         argv[argc] = NULL;
408         status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
409                         | RUN_COMMAND_STDOUT_TO_STDERR);
410 }
411
412 static void execute_commands(const char *unpacker_error)
413 {
414         struct command *cmd = commands;
415         unsigned char sha1[20];
416
417         if (unpacker_error) {
418                 while (cmd) {
419                         cmd->error_string = "n/a (unpacker error)";
420                         cmd = cmd->next;
421                 }
422                 return;
423         }
424
425         if (run_receive_hook(pre_receive_hook)) {
426                 while (cmd) {
427                         cmd->error_string = "pre-receive hook declined";
428                         cmd = cmd->next;
429                 }
430                 return;
431         }
432
433         head_name = resolve_ref("HEAD", sha1, 0, NULL);
434
435         while (cmd) {
436                 cmd->error_string = update(cmd);
437                 cmd = cmd->next;
438         }
439 }
440
441 static void read_head_info(void)
442 {
443         struct command **p = &commands;
444         for (;;) {
445                 static char line[1000];
446                 unsigned char old_sha1[20], new_sha1[20];
447                 struct command *cmd;
448                 char *refname;
449                 int len, reflen;
450
451                 len = packet_read_line(0, line, sizeof(line));
452                 if (!len)
453                         break;
454                 if (line[len-1] == '\n')
455                         line[--len] = 0;
456                 if (len < 83 ||
457                     line[40] != ' ' ||
458                     line[81] != ' ' ||
459                     get_sha1_hex(line, old_sha1) ||
460                     get_sha1_hex(line + 41, new_sha1))
461                         die("protocol error: expected old/new/ref, got '%s'",
462                             line);
463
464                 refname = line + 82;
465                 reflen = strlen(refname);
466                 if (reflen + 82 < len) {
467                         if (strstr(refname + reflen + 1, "report-status"))
468                                 report_status = 1;
469                 }
470                 cmd = xmalloc(sizeof(struct command) + len - 80);
471                 hashcpy(cmd->old_sha1, old_sha1);
472                 hashcpy(cmd->new_sha1, new_sha1);
473                 memcpy(cmd->ref_name, line + 82, len - 81);
474                 cmd->error_string = NULL;
475                 cmd->next = NULL;
476                 *p = cmd;
477                 p = &cmd->next;
478         }
479 }
480
481 static const char *parse_pack_header(struct pack_header *hdr)
482 {
483         switch (read_pack_header(0, hdr)) {
484         case PH_ERROR_EOF:
485                 return "eof before pack header was fully read";
486
487         case PH_ERROR_PACK_SIGNATURE:
488                 return "protocol error (pack signature mismatch detected)";
489
490         case PH_ERROR_PROTOCOL:
491                 return "protocol error (pack version unsupported)";
492
493         default:
494                 return "unknown error in parse_pack_header";
495
496         case 0:
497                 return NULL;
498         }
499 }
500
501 static const char *pack_lockfile;
502
503 static const char *unpack(void)
504 {
505         struct pack_header hdr;
506         const char *hdr_err;
507         char hdr_arg[38];
508
509         hdr_err = parse_pack_header(&hdr);
510         if (hdr_err)
511                 return hdr_err;
512         snprintf(hdr_arg, sizeof(hdr_arg),
513                         "--pack_header=%"PRIu32",%"PRIu32,
514                         ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
515
516         if (ntohl(hdr.hdr_entries) < unpack_limit) {
517                 int code, i = 0;
518                 const char *unpacker[4];
519                 unpacker[i++] = "unpack-objects";
520                 if (receive_fsck_objects)
521                         unpacker[i++] = "--strict";
522                 unpacker[i++] = hdr_arg;
523                 unpacker[i++] = NULL;
524                 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
525                 if (!code)
526                         return NULL;
527                 return "unpack-objects abnormal exit";
528         } else {
529                 const char *keeper[7];
530                 int s, status, i = 0;
531                 char keep_arg[256];
532                 struct child_process ip;
533
534                 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
535                 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
536                         strcpy(keep_arg + s, "localhost");
537
538                 keeper[i++] = "index-pack";
539                 keeper[i++] = "--stdin";
540                 if (receive_fsck_objects)
541                         keeper[i++] = "--strict";
542                 keeper[i++] = "--fix-thin";
543                 keeper[i++] = hdr_arg;
544                 keeper[i++] = keep_arg;
545                 keeper[i++] = NULL;
546                 memset(&ip, 0, sizeof(ip));
547                 ip.argv = keeper;
548                 ip.out = -1;
549                 ip.git_cmd = 1;
550                 status = start_command(&ip);
551                 if (status) {
552                         return "index-pack fork failed";
553                 }
554                 pack_lockfile = index_pack_lockfile(ip.out);
555                 close(ip.out);
556                 status = finish_command(&ip);
557                 if (!status) {
558                         reprepare_packed_git();
559                         return NULL;
560                 }
561                 return "index-pack abnormal exit";
562         }
563 }
564
565 static void report(const char *unpack_status)
566 {
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);
579 }
580
581 static int delete_only(struct command *cmd)
582 {
583         while (cmd) {
584                 if (!is_null_sha1(cmd->new_sha1))
585                         return 0;
586                 cmd = cmd->next;
587         }
588         return 1;
589 }
590
591 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
592 {
593         char *other;
594         size_t len;
595         struct remote *remote;
596         struct transport *transport;
597         const struct ref *extra;
598
599         e->name[-1] = '\0';
600         other = xstrdup(make_absolute_path(e->base));
601         e->name[-1] = '/';
602         len = strlen(other);
603
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;
623 }
624
625 static void add_alternate_refs(void)
626 {
627         foreach_alt_odb(add_refs_from_alternate, NULL);
628 }
629
630 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
631 {
632         int advertise_refs = 0;
633         int stateless_rpc = 0;
634         int i;
635         char *dir = NULL;
636
637         argv++;
638         for (i = 1; i < argc; i++) {
639                 const char *arg = *argv++;
640
641                 if (*arg == '-') {
642                         if (!strcmp(arg, "--advertise-refs")) {
643                                 advertise_refs = 1;
644                                 continue;
645                         }
646                         if (!strcmp(arg, "--stateless-rpc")) {
647                                 stateless_rpc = 1;
648                                 continue;
649                         }
650
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         if (advertise_refs || !stateless_rpc) {
676                 add_alternate_refs();
677                 write_head_info();
678                 clear_extra_refs();
679
680                 /* EOF */
681                 packet_flush(1);
682         }
683         if (advertise_refs)
684                 return 0;
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                 if (auto_gc) {
700                         const char *argv_gc_auto[] = {
701                                 "gc", "--auto", "--quiet", NULL,
702                         };
703                         run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
704                 }
705                 if (auto_update_server_info)
706                         update_server_info(0);
707         }
708         return 0;
709 }