Remove a left-over file from t/t5100
[git/dscho.git] / builtin-receive-pack.c
blobb771fe9b20f4c4d6e19289f428442d489aba6896
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,
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)
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;
49 static int receive_pack_config(const char *var, const char *value, void *cb)
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);
94 static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
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 */
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_receive_hook(const char *hook_name)
128         static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
129         struct command *cmd;
130         struct child_process proc;
131         const char *argv[2];
132         int have_input = 0, code;
134         for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
135                 if (!cmd->error_string)
136                         have_input = 1;
137         }
139         if (!have_input || access(hook_name, X_OK) < 0)
140                 return 0;
142         argv[0] = hook_name;
143         argv[1] = NULL;
145         memset(&proc, 0, sizeof(proc));
146         proc.argv = argv;
147         proc.in = -1;
148         proc.stdout_to_stderr = 1;
150         code = start_command(&proc);
151         if (code)
152                 return code;
153         for (cmd = commands; cmd; cmd = cmd->next) {
154                 if (!cmd->error_string) {
155                         size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
156                                 sha1_to_hex(cmd->old_sha1),
157                                 sha1_to_hex(cmd->new_sha1),
158                                 cmd->ref_name);
159                         if (write_in_full(proc.in, buf, n) != n)
160                                 break;
161                 }
162         }
163         close(proc.in);
164         return finish_command(&proc);
167 static int run_update_hook(struct command *cmd)
169         static const char update_hook[] = "hooks/update";
170         const char *argv[5];
172         if (access(update_hook, X_OK) < 0)
173                 return 0;
175         argv[0] = update_hook;
176         argv[1] = cmd->ref_name;
177         argv[2] = sha1_to_hex(cmd->old_sha1);
178         argv[3] = sha1_to_hex(cmd->new_sha1);
179         argv[4] = NULL;
181         return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
182                                         RUN_COMMAND_STDOUT_TO_STDERR);
185 static int is_ref_checked_out(const char *ref)
187         if (is_bare_repository())
188                 return 0;
190         if (!head_name)
191                 return 0;
192         return !strcmp(head_name, ref);
195 static char *warn_unconfigured_deny_msg[] = {
196         "Updating the currently checked out branch may cause confusion,",
197         "as the index and work tree do not reflect changes that are in HEAD.",
198         "As a result, you may see the changes you just pushed into it",
199         "reverted when you run 'git diff' over there, and you may want",
200         "to run 'git reset --hard' before starting to work to recover.",
201         "",
202         "You can set 'receive.denyCurrentBranch' configuration variable to",
203         "'refuse' in the remote repository to forbid pushing into its",
204         "current branch."
205         "",
206         "To allow pushing into the current branch, you can set it to 'ignore';",
207         "but this is not recommended unless you arranged to update its work",
208         "tree to match what you pushed in some other way.",
209         "",
210         "To squelch this message, you can set it to 'warn'.",
211         "",
212         "Note that the default will change in a future version of git",
213         "to refuse updating the current branch unless you have the",
214         "configuration variable set to either 'ignore' or 'warn'."
217 static void warn_unconfigured_deny(void)
219         int i;
220         for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
221                 warning("%s", warn_unconfigured_deny_msg[i]);
224 static char *warn_unconfigured_deny_delete_current_msg[] = {
225         "Deleting the current branch can cause confusion by making the next",
226         "'git clone' not check out any file.",
227         "",
228         "You can set 'receive.denyDeleteCurrent' configuration variable to",
229         "'refuse' in the remote repository to disallow deleting the current",
230         "branch.",
231         "",
232         "You can set it to 'ignore' to allow such a delete without a warning.",
233         "",
234         "To make this warning message less loud, you can set it to 'warn'.",
235         "",
236         "Note that the default will change in a future version of git",
237         "to refuse deleting the current branch unless you have the",
238         "configuration variable set to either 'ignore' or 'warn'."
241 static void warn_unconfigured_deny_delete_current(void)
243         int i;
244         for (i = 0;
245              i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
246              i++)
247                 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
250 static const char *update(struct command *cmd)
252         const char *name = cmd->ref_name;
253         unsigned char *old_sha1 = cmd->old_sha1;
254         unsigned char *new_sha1 = cmd->new_sha1;
255         struct ref_lock *lock;
257         /* only refs/... are allowed */
258         if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
259                 error("refusing to create funny ref '%s' remotely", name);
260                 return "funny refname";
261         }
263         if (is_ref_checked_out(name)) {
264                 switch (deny_current_branch) {
265                 case DENY_IGNORE:
266                         break;
267                 case DENY_UNCONFIGURED:
268                 case DENY_WARN:
269                         warning("updating the current branch");
270                         if (deny_current_branch == DENY_UNCONFIGURED)
271                                 warn_unconfigured_deny();
272                         break;
273                 case DENY_REFUSE:
274                         error("refusing to update checked out branch: %s", name);
275                         return "branch is currently checked out";
276                 }
277         }
279         if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
280                 error("unpack should have generated %s, "
281                       "but I can't find it!", sha1_to_hex(new_sha1));
282                 return "bad pack";
283         }
285         if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
286                 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
287                         error("denying ref deletion for %s", name);
288                         return "deletion prohibited";
289                 }
291                 if (!strcmp(name, head_name)) {
292                         switch (deny_delete_current) {
293                         case DENY_IGNORE:
294                                 break;
295                         case DENY_WARN:
296                         case DENY_UNCONFIGURED:
297                                 if (deny_delete_current == DENY_UNCONFIGURED)
298                                         warn_unconfigured_deny_delete_current();
299                                 warning("deleting the current branch");
300                                 break;
301                         case DENY_REFUSE:
302                                 error("refusing to delete the current branch: %s", name);
303                                 return "deletion of the current branch prohibited";
304                         }
305                 }
306         }
308         if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
309             !is_null_sha1(old_sha1) &&
310             !prefixcmp(name, "refs/heads/")) {
311                 struct object *old_object, *new_object;
312                 struct commit *old_commit, *new_commit;
313                 struct commit_list *bases, *ent;
315                 old_object = parse_object(old_sha1);
316                 new_object = parse_object(new_sha1);
318                 if (!old_object || !new_object ||
319                     old_object->type != OBJ_COMMIT ||
320                     new_object->type != OBJ_COMMIT) {
321                         error("bad sha1 objects for %s", name);
322                         return "bad ref";
323                 }
324                 old_commit = (struct commit *)old_object;
325                 new_commit = (struct commit *)new_object;
326                 bases = get_merge_bases(old_commit, new_commit, 1);
327                 for (ent = bases; ent; ent = ent->next)
328                         if (!hashcmp(old_sha1, ent->item->object.sha1))
329                                 break;
330                 free_commit_list(bases);
331                 if (!ent) {
332                         error("denying non-fast forward %s"
333                               " (you should pull first)", name);
334                         return "non-fast forward";
335                 }
336         }
337         if (run_update_hook(cmd)) {
338                 error("hook declined to update %s", name);
339                 return "hook declined";
340         }
342         if (is_null_sha1(new_sha1)) {
343                 if (!parse_object(old_sha1)) {
344                         warning ("Allowing deletion of corrupt ref.");
345                         old_sha1 = NULL;
346                 }
347                 if (delete_ref(name, old_sha1, 0)) {
348                         error("failed to delete %s", name);
349                         return "failed to delete";
350                 }
351                 return NULL; /* good */
352         }
353         else {
354                 lock = lock_any_ref_for_update(name, old_sha1, 0);
355                 if (!lock) {
356                         error("failed to lock %s", name);
357                         return "failed to lock";
358                 }
359                 if (write_ref_sha1(lock, new_sha1, "push")) {
360                         return "failed to write"; /* error() already called */
361                 }
362                 return NULL; /* good */
363         }
366 static char update_post_hook[] = "hooks/post-update";
368 static void run_update_post_hook(struct command *cmd)
370         struct command *cmd_p;
371         int argc, status;
372         const char **argv;
374         for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
375                 if (cmd_p->error_string)
376                         continue;
377                 argc++;
378         }
379         if (!argc || access(update_post_hook, X_OK) < 0)
380                 return;
381         argv = xmalloc(sizeof(*argv) * (2 + argc));
382         argv[0] = update_post_hook;
384         for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
385                 char *p;
386                 if (cmd_p->error_string)
387                         continue;
388                 p = xmalloc(strlen(cmd_p->ref_name) + 1);
389                 strcpy(p, cmd_p->ref_name);
390                 argv[argc] = p;
391                 argc++;
392         }
393         argv[argc] = NULL;
394         status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
395                         | RUN_COMMAND_STDOUT_TO_STDERR);
398 static void execute_commands(const char *unpacker_error)
400         struct command *cmd = commands;
401         unsigned char sha1[20];
403         if (unpacker_error) {
404                 while (cmd) {
405                         cmd->error_string = "n/a (unpacker error)";
406                         cmd = cmd->next;
407                 }
408                 return;
409         }
411         if (run_receive_hook(pre_receive_hook)) {
412                 while (cmd) {
413                         cmd->error_string = "pre-receive hook declined";
414                         cmd = cmd->next;
415                 }
416                 return;
417         }
419         head_name = resolve_ref("HEAD", sha1, 0, NULL);
421         while (cmd) {
422                 cmd->error_string = update(cmd);
423                 cmd = cmd->next;
424         }
427 static void read_head_info(void)
429         struct command **p = &commands;
430         for (;;) {
431                 static char line[1000];
432                 unsigned char old_sha1[20], new_sha1[20];
433                 struct command *cmd;
434                 char *refname;
435                 int len, reflen;
437                 len = packet_read_line(0, line, sizeof(line));
438                 if (!len)
439                         break;
440                 if (line[len-1] == '\n')
441                         line[--len] = 0;
442                 if (len < 83 ||
443                     line[40] != ' ' ||
444                     line[81] != ' ' ||
445                     get_sha1_hex(line, old_sha1) ||
446                     get_sha1_hex(line + 41, new_sha1))
447                         die("protocol error: expected old/new/ref, got '%s'",
448                             line);
450                 refname = line + 82;
451                 reflen = strlen(refname);
452                 if (reflen + 82 < len) {
453                         if (strstr(refname + reflen + 1, "report-status"))
454                                 report_status = 1;
455                 }
456                 cmd = xmalloc(sizeof(struct command) + len - 80);
457                 hashcpy(cmd->old_sha1, old_sha1);
458                 hashcpy(cmd->new_sha1, new_sha1);
459                 memcpy(cmd->ref_name, line + 82, len - 81);
460                 cmd->error_string = NULL;
461                 cmd->next = NULL;
462                 *p = cmd;
463                 p = &cmd->next;
464         }
467 static const char *parse_pack_header(struct pack_header *hdr)
469         switch (read_pack_header(0, hdr)) {
470         case PH_ERROR_EOF:
471                 return "eof before pack header was fully read";
473         case PH_ERROR_PACK_SIGNATURE:
474                 return "protocol error (pack signature mismatch detected)";
476         case PH_ERROR_PROTOCOL:
477                 return "protocol error (pack version unsupported)";
479         default:
480                 return "unknown error in parse_pack_header";
482         case 0:
483                 return NULL;
484         }
487 static const char *pack_lockfile;
489 static const char *unpack(void)
491         struct pack_header hdr;
492         const char *hdr_err;
493         char hdr_arg[38];
495         hdr_err = parse_pack_header(&hdr);
496         if (hdr_err)
497                 return hdr_err;
498         snprintf(hdr_arg, sizeof(hdr_arg),
499                         "--pack_header=%"PRIu32",%"PRIu32,
500                         ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
502         if (ntohl(hdr.hdr_entries) < unpack_limit) {
503                 int code, i = 0;
504                 const char *unpacker[4];
505                 unpacker[i++] = "unpack-objects";
506                 if (receive_fsck_objects)
507                         unpacker[i++] = "--strict";
508                 unpacker[i++] = hdr_arg;
509                 unpacker[i++] = NULL;
510                 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
511                 if (!code)
512                         return NULL;
513                 return "unpack-objects abnormal exit";
514         } else {
515                 const char *keeper[7];
516                 int s, status, i = 0;
517                 char keep_arg[256];
518                 struct child_process ip;
520                 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
521                 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
522                         strcpy(keep_arg + s, "localhost");
524                 keeper[i++] = "index-pack";
525                 keeper[i++] = "--stdin";
526                 if (receive_fsck_objects)
527                         keeper[i++] = "--strict";
528                 keeper[i++] = "--fix-thin";
529                 keeper[i++] = hdr_arg;
530                 keeper[i++] = keep_arg;
531                 keeper[i++] = NULL;
532                 memset(&ip, 0, sizeof(ip));
533                 ip.argv = keeper;
534                 ip.out = -1;
535                 ip.git_cmd = 1;
536                 status = start_command(&ip);
537                 if (status) {
538                         return "index-pack fork failed";
539                 }
540                 pack_lockfile = index_pack_lockfile(ip.out);
541                 close(ip.out);
542                 status = finish_command(&ip);
543                 if (!status) {
544                         reprepare_packed_git();
545                         return NULL;
546                 }
547                 return "index-pack abnormal exit";
548         }
551 static void report(const char *unpack_status)
553         struct command *cmd;
554         packet_write(1, "unpack %s\n",
555                      unpack_status ? unpack_status : "ok");
556         for (cmd = commands; cmd; cmd = cmd->next) {
557                 if (!cmd->error_string)
558                         packet_write(1, "ok %s\n",
559                                      cmd->ref_name);
560                 else
561                         packet_write(1, "ng %s %s\n",
562                                      cmd->ref_name, cmd->error_string);
563         }
564         packet_flush(1);
567 static int delete_only(struct command *cmd)
569         while (cmd) {
570                 if (!is_null_sha1(cmd->new_sha1))
571                         return 0;
572                 cmd = cmd->next;
573         }
574         return 1;
577 static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
579         char *other;
580         size_t len;
581         struct remote *remote;
582         struct transport *transport;
583         const struct ref *extra;
585         e->name[-1] = '\0';
586         other = xstrdup(make_absolute_path(e->base));
587         e->name[-1] = '/';
588         len = strlen(other);
590         while (other[len-1] == '/')
591                 other[--len] = '\0';
592         if (len < 8 || memcmp(other + len - 8, "/objects", 8))
593                 return 0;
594         /* Is this a git repository with refs? */
595         memcpy(other + len - 8, "/refs", 6);
596         if (!is_directory(other))
597                 return 0;
598         other[len - 8] = '\0';
599         remote = remote_get(other);
600         transport = transport_get(remote, other);
601         for (extra = transport_get_remote_refs(transport);
602              extra;
603              extra = extra->next) {
604                 add_extra_ref(".have", extra->old_sha1, 0);
605         }
606         transport_disconnect(transport);
607         free(other);
608         return 0;
611 static void add_alternate_refs(void)
613         foreach_alt_odb(add_refs_from_alternate, NULL);
616 int cmd_receive_pack(int argc, const char **argv, const char *prefix)
618         int i;
619         char *dir = NULL;
621         argv++;
622         for (i = 1; i < argc; i++) {
623                 const char *arg = *argv++;
625                 if (*arg == '-') {
626                         /* Do flag handling here */
627                         usage(receive_pack_usage);
628                 }
629                 if (dir)
630                         usage(receive_pack_usage);
631                 dir = xstrdup(arg);
632         }
633         if (!dir)
634                 usage(receive_pack_usage);
636         setup_path();
638         if (!enter_repo(dir, 0))
639                 die("'%s' does not appear to be a git repository", dir);
641         if (is_repository_shallow())
642                 die("attempt to push into a shallow repository");
644         git_config(receive_pack_config, NULL);
646         if (0 <= transfer_unpack_limit)
647                 unpack_limit = transfer_unpack_limit;
648         else if (0 <= receive_unpack_limit)
649                 unpack_limit = receive_unpack_limit;
651         capabilities_to_send = (prefer_ofs_delta) ?
652                 " report-status delete-refs ofs-delta " :
653                 " report-status delete-refs ";
655         add_alternate_refs();
656         write_head_info();
657         clear_extra_refs();
659         /* EOF */
660         packet_flush(1);
662         read_head_info();
663         if (commands) {
664                 const char *unpack_status = NULL;
666                 if (!delete_only(commands))
667                         unpack_status = unpack();
668                 execute_commands(unpack_status);
669                 if (pack_lockfile)
670                         unlink_or_warn(pack_lockfile);
671                 if (report_status)
672                         report(unpack_status);
673                 run_receive_hook(post_receive_hook);
674                 run_update_post_hook(commands);
675         }
676         return 0;