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