builtin-receive-pack.con commit mergetool: respect autocrlf by using checkout-index (0ec7b6c)
   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
  14enum deny_action {
  15        DENY_IGNORE,
  16        DENY_WARN,
  17        DENY_REFUSE,
  18};
  19
  20static int deny_deletes = 0;
  21static int deny_non_fast_forwards = 0;
  22static enum deny_action deny_current_branch = DENY_WARN;
  23static int receive_fsck_objects;
  24static int receive_unpack_limit = -1;
  25static int transfer_unpack_limit = -1;
  26static int unpack_limit = 100;
  27static int report_status;
  28
  29static char capabilities[] = " report-status delete-refs ";
  30static int capabilities_sent;
  31
  32static 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
  47static 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
  82static 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
  93static 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
 101struct 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
 109static struct command *commands;
 110
 111static const char pre_receive_hook[] = "hooks/pre-receive";
 112static const char post_receive_hook[] = "hooks/post-receive";
 113
 114static 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
 139static int run_receive_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
 180static 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
 203static 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
 217static 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
 317static char update_post_hook[] = "hooks/post-update";
 318
 319static 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
 349static 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_receive_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
 375static 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
 415static 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
 435static const char *pack_lockfile;
 436
 437static 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
 512static 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
 528static 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
 538static 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
 572static void add_alternate_refs(void)
 573{
 574        foreach_alt_odb(add_refs_from_alternate, NULL);
 575}
 576
 577int 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_receive_hook(post_receive_hook);
 631                run_update_post_hook(commands);
 632        }
 633        return 0;
 634}