builtin-receive-pack.con commit Merge branch 'jc/color-attrs' into maint (0476228)
   1#include "cache.h"
   2#include "pack.h"
   3#include "refs.h"
   4#include "pkt-line.h"
   5#include "sideband.h"
   6#include "run-command.h"
   7#include "exec_cmd.h"
   8#include "commit.h"
   9#include "object.h"
  10#include "remote.h"
  11#include "transport.h"
  12
  13static const char receive_pack_usage[] = "git receive-pack <git-dir>";
  14
  15enum deny_action {
  16        DENY_UNCONFIGURED,
  17        DENY_IGNORE,
  18        DENY_WARN,
  19        DENY_REFUSE,
  20};
  21
  22static int deny_deletes;
  23static int deny_non_fast_forwards;
  24static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
  25static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
  26static int receive_fsck_objects;
  27static int receive_unpack_limit = -1;
  28static int transfer_unpack_limit = -1;
  29static int unpack_limit = 100;
  30static int report_status;
  31static int use_sideband;
  32static int prefer_ofs_delta = 1;
  33static int auto_update_server_info;
  34static int auto_gc = 1;
  35static const char *head_name;
  36static int sent_capabilities;
  37
  38static enum deny_action parse_deny_action(const char *var, const char *value)
  39{
  40        if (value) {
  41                if (!strcasecmp(value, "ignore"))
  42                        return DENY_IGNORE;
  43                if (!strcasecmp(value, "warn"))
  44                        return DENY_WARN;
  45                if (!strcasecmp(value, "refuse"))
  46                        return DENY_REFUSE;
  47        }
  48        if (git_config_bool(var, value))
  49                return DENY_REFUSE;
  50        return DENY_IGNORE;
  51}
  52
  53static int receive_pack_config(const char *var, const char *value, void *cb)
  54{
  55        if (strcmp(var, "receive.denydeletes") == 0) {
  56                deny_deletes = git_config_bool(var, value);
  57                return 0;
  58        }
  59
  60        if (strcmp(var, "receive.denynonfastforwards") == 0) {
  61                deny_non_fast_forwards = git_config_bool(var, value);
  62                return 0;
  63        }
  64
  65        if (strcmp(var, "receive.unpacklimit") == 0) {
  66                receive_unpack_limit = git_config_int(var, value);
  67                return 0;
  68        }
  69
  70        if (strcmp(var, "transfer.unpacklimit") == 0) {
  71                transfer_unpack_limit = git_config_int(var, value);
  72                return 0;
  73        }
  74
  75        if (strcmp(var, "receive.fsckobjects") == 0) {
  76                receive_fsck_objects = git_config_bool(var, value);
  77                return 0;
  78        }
  79
  80        if (!strcmp(var, "receive.denycurrentbranch")) {
  81                deny_current_branch = parse_deny_action(var, value);
  82                return 0;
  83        }
  84
  85        if (strcmp(var, "receive.denydeletecurrent") == 0) {
  86                deny_delete_current = parse_deny_action(var, value);
  87                return 0;
  88        }
  89
  90        if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
  91                prefer_ofs_delta = git_config_bool(var, value);
  92                return 0;
  93        }
  94
  95        if (strcmp(var, "receive.updateserverinfo") == 0) {
  96                auto_update_server_info = git_config_bool(var, value);
  97                return 0;
  98        }
  99
 100        if (strcmp(var, "receive.autogc") == 0) {
 101                auto_gc = git_config_bool(var, value);
 102                return 0;
 103        }
 104
 105        return git_default_config(var, value, cb);
 106}
 107
 108static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
 109{
 110        if (sent_capabilities)
 111                packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
 112        else
 113                packet_write(1, "%s %s%c%s%s\n",
 114                             sha1_to_hex(sha1), path, 0,
 115                             " report-status delete-refs side-band-64k",
 116                             prefer_ofs_delta ? " ofs-delta" : "");
 117        sent_capabilities = 1;
 118        return 0;
 119}
 120
 121static void write_head_info(void)
 122{
 123        for_each_ref(show_ref, NULL);
 124        if (!sent_capabilities)
 125                show_ref("capabilities^{}", null_sha1, 0, NULL);
 126
 127}
 128
 129struct command {
 130        struct command *next;
 131        const char *error_string;
 132        unsigned char old_sha1[20];
 133        unsigned char new_sha1[20];
 134        char ref_name[FLEX_ARRAY]; /* more */
 135};
 136
 137static struct command *commands;
 138
 139static const char pre_receive_hook[] = "hooks/pre-receive";
 140static const char post_receive_hook[] = "hooks/post-receive";
 141
 142static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 143static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 144
 145static void report_message(const char *prefix, const char *err, va_list params)
 146{
 147        int sz = strlen(prefix);
 148        char msg[4096];
 149
 150        strncpy(msg, prefix, sz);
 151        sz += vsnprintf(msg + sz, sizeof(msg) - sz, err, params);
 152        if (sz > (sizeof(msg) - 1))
 153                sz = sizeof(msg) - 1;
 154        msg[sz++] = '\n';
 155
 156        if (use_sideband)
 157                send_sideband(1, 2, msg, sz, use_sideband);
 158        else
 159                xwrite(2, msg, sz);
 160}
 161
 162static void rp_warning(const char *err, ...)
 163{
 164        va_list params;
 165        va_start(params, err);
 166        report_message("warning: ", err, params);
 167        va_end(params);
 168}
 169
 170static void rp_error(const char *err, ...)
 171{
 172        va_list params;
 173        va_start(params, err);
 174        report_message("error: ", err, params);
 175        va_end(params);
 176}
 177
 178static int copy_to_sideband(int in, int out, void *arg)
 179{
 180        char data[128];
 181        while (1) {
 182                ssize_t sz = xread(in, data, sizeof(data));
 183                if (sz <= 0)
 184                        break;
 185                send_sideband(1, 2, data, sz, use_sideband);
 186        }
 187        close(in);
 188        return 0;
 189}
 190
 191static int run_receive_hook(const char *hook_name)
 192{
 193        static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
 194        struct command *cmd;
 195        struct child_process proc;
 196        struct async muxer;
 197        const char *argv[2];
 198        int have_input = 0, code;
 199
 200        for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
 201                if (!cmd->error_string)
 202                        have_input = 1;
 203        }
 204
 205        if (!have_input || access(hook_name, X_OK) < 0)
 206                return 0;
 207
 208        argv[0] = hook_name;
 209        argv[1] = NULL;
 210
 211        memset(&proc, 0, sizeof(proc));
 212        proc.argv = argv;
 213        proc.in = -1;
 214        proc.stdout_to_stderr = 1;
 215
 216        if (use_sideband) {
 217                memset(&muxer, 0, sizeof(muxer));
 218                muxer.proc = copy_to_sideband;
 219                muxer.in = -1;
 220                code = start_async(&muxer);
 221                if (code)
 222                        return code;
 223                proc.err = muxer.in;
 224        }
 225
 226        code = start_command(&proc);
 227        if (code) {
 228                if (use_sideband)
 229                        finish_async(&muxer);
 230                return code;
 231        }
 232
 233        for (cmd = commands; cmd; cmd = cmd->next) {
 234                if (!cmd->error_string) {
 235                        size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
 236                                sha1_to_hex(cmd->old_sha1),
 237                                sha1_to_hex(cmd->new_sha1),
 238                                cmd->ref_name);
 239                        if (write_in_full(proc.in, buf, n) != n)
 240                                break;
 241                }
 242        }
 243        close(proc.in);
 244        if (use_sideband)
 245                finish_async(&muxer);
 246        return finish_command(&proc);
 247}
 248
 249static int run_update_hook(struct command *cmd)
 250{
 251        static const char update_hook[] = "hooks/update";
 252        const char *argv[5];
 253        struct child_process proc;
 254        int code;
 255
 256        if (access(update_hook, X_OK) < 0)
 257                return 0;
 258
 259        argv[0] = update_hook;
 260        argv[1] = cmd->ref_name;
 261        argv[2] = sha1_to_hex(cmd->old_sha1);
 262        argv[3] = sha1_to_hex(cmd->new_sha1);
 263        argv[4] = NULL;
 264
 265        memset(&proc, 0, sizeof(proc));
 266        proc.no_stdin = 1;
 267        proc.stdout_to_stderr = 1;
 268        proc.err = use_sideband ? -1 : 0;
 269        proc.argv = argv;
 270
 271        code = start_command(&proc);
 272        if (code)
 273                return code;
 274        if (use_sideband)
 275                copy_to_sideband(proc.err, -1, NULL);
 276        return finish_command(&proc);
 277}
 278
 279static int is_ref_checked_out(const char *ref)
 280{
 281        if (is_bare_repository())
 282                return 0;
 283
 284        if (!head_name)
 285                return 0;
 286        return !strcmp(head_name, ref);
 287}
 288
 289static char *refuse_unconfigured_deny_msg[] = {
 290        "By default, updating the current branch in a non-bare repository",
 291        "is denied, because it will make the index and work tree inconsistent",
 292        "with what you pushed, and will require 'git reset --hard' to match",
 293        "the work tree to HEAD.",
 294        "",
 295        "You can set 'receive.denyCurrentBranch' configuration variable to",
 296        "'ignore' or 'warn' in the remote repository to allow pushing into",
 297        "its current branch; however, this is not recommended unless you",
 298        "arranged to update its work tree to match what you pushed in some",
 299        "other way.",
 300        "",
 301        "To squelch this message and still keep the default behaviour, set",
 302        "'receive.denyCurrentBranch' configuration variable to 'refuse'."
 303};
 304
 305static void refuse_unconfigured_deny(void)
 306{
 307        int i;
 308        for (i = 0; i < ARRAY_SIZE(refuse_unconfigured_deny_msg); i++)
 309                rp_error("%s", refuse_unconfigured_deny_msg[i]);
 310}
 311
 312static char *refuse_unconfigured_deny_delete_current_msg[] = {
 313        "By default, deleting the current branch is denied, because the next",
 314        "'git clone' won't result in any file checked out, causing confusion.",
 315        "",
 316        "You can set 'receive.denyDeleteCurrent' configuration variable to",
 317        "'warn' or 'ignore' in the remote repository to allow deleting the",
 318        "current branch, with or without a warning message.",
 319        "",
 320        "To squelch this message, you can set it to 'refuse'."
 321};
 322
 323static void refuse_unconfigured_deny_delete_current(void)
 324{
 325        int i;
 326        for (i = 0;
 327             i < ARRAY_SIZE(refuse_unconfigured_deny_delete_current_msg);
 328             i++)
 329                rp_error("%s", refuse_unconfigured_deny_delete_current_msg[i]);
 330}
 331
 332static const char *update(struct command *cmd)
 333{
 334        const char *name = cmd->ref_name;
 335        unsigned char *old_sha1 = cmd->old_sha1;
 336        unsigned char *new_sha1 = cmd->new_sha1;
 337        struct ref_lock *lock;
 338
 339        /* only refs/... are allowed */
 340        if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
 341                rp_error("refusing to create funny ref '%s' remotely", name);
 342                return "funny refname";
 343        }
 344
 345        if (is_ref_checked_out(name)) {
 346                switch (deny_current_branch) {
 347                case DENY_IGNORE:
 348                        break;
 349                case DENY_WARN:
 350                        rp_warning("updating the current branch");
 351                        break;
 352                case DENY_REFUSE:
 353                case DENY_UNCONFIGURED:
 354                        rp_error("refusing to update checked out branch: %s", name);
 355                        if (deny_current_branch == DENY_UNCONFIGURED)
 356                                refuse_unconfigured_deny();
 357                        return "branch is currently checked out";
 358                }
 359        }
 360
 361        if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
 362                error("unpack should have generated %s, "
 363                      "but I can't find it!", sha1_to_hex(new_sha1));
 364                return "bad pack";
 365        }
 366
 367        if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
 368                if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
 369                        rp_error("denying ref deletion for %s", name);
 370                        return "deletion prohibited";
 371                }
 372
 373                if (!strcmp(name, head_name)) {
 374                        switch (deny_delete_current) {
 375                        case DENY_IGNORE:
 376                                break;
 377                        case DENY_WARN:
 378                                rp_warning("deleting the current branch");
 379                                break;
 380                        case DENY_REFUSE:
 381                        case DENY_UNCONFIGURED:
 382                                if (deny_delete_current == DENY_UNCONFIGURED)
 383                                        refuse_unconfigured_deny_delete_current();
 384                                rp_error("refusing to delete the current branch: %s", name);
 385                                return "deletion of the current branch prohibited";
 386                        }
 387                }
 388        }
 389
 390        if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
 391            !is_null_sha1(old_sha1) &&
 392            !prefixcmp(name, "refs/heads/")) {
 393                struct object *old_object, *new_object;
 394                struct commit *old_commit, *new_commit;
 395                struct commit_list *bases, *ent;
 396
 397                old_object = parse_object(old_sha1);
 398                new_object = parse_object(new_sha1);
 399
 400                if (!old_object || !new_object ||
 401                    old_object->type != OBJ_COMMIT ||
 402                    new_object->type != OBJ_COMMIT) {
 403                        error("bad sha1 objects for %s", name);
 404                        return "bad ref";
 405                }
 406                old_commit = (struct commit *)old_object;
 407                new_commit = (struct commit *)new_object;
 408                bases = get_merge_bases(old_commit, new_commit, 1);
 409                for (ent = bases; ent; ent = ent->next)
 410                        if (!hashcmp(old_sha1, ent->item->object.sha1))
 411                                break;
 412                free_commit_list(bases);
 413                if (!ent) {
 414                        rp_error("denying non-fast-forward %s"
 415                                 " (you should pull first)", name);
 416                        return "non-fast-forward";
 417                }
 418        }
 419        if (run_update_hook(cmd)) {
 420                rp_error("hook declined to update %s", name);
 421                return "hook declined";
 422        }
 423
 424        if (is_null_sha1(new_sha1)) {
 425                if (!parse_object(old_sha1)) {
 426                        rp_warning("Allowing deletion of corrupt ref.");
 427                        old_sha1 = NULL;
 428                }
 429                if (delete_ref(name, old_sha1, 0)) {
 430                        rp_error("failed to delete %s", name);
 431                        return "failed to delete";
 432                }
 433                return NULL; /* good */
 434        }
 435        else {
 436                lock = lock_any_ref_for_update(name, old_sha1, 0);
 437                if (!lock) {
 438                        rp_error("failed to lock %s", name);
 439                        return "failed to lock";
 440                }
 441                if (write_ref_sha1(lock, new_sha1, "push")) {
 442                        return "failed to write"; /* error() already called */
 443                }
 444                return NULL; /* good */
 445        }
 446}
 447
 448static char update_post_hook[] = "hooks/post-update";
 449
 450static void run_update_post_hook(struct command *cmd)
 451{
 452        struct command *cmd_p;
 453        int argc;
 454        const char **argv;
 455        struct child_process proc;
 456
 457        for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
 458                if (cmd_p->error_string)
 459                        continue;
 460                argc++;
 461        }
 462        if (!argc || access(update_post_hook, X_OK) < 0)
 463                return;
 464        argv = xmalloc(sizeof(*argv) * (2 + argc));
 465        argv[0] = update_post_hook;
 466
 467        for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
 468                char *p;
 469                if (cmd_p->error_string)
 470                        continue;
 471                p = xmalloc(strlen(cmd_p->ref_name) + 1);
 472                strcpy(p, cmd_p->ref_name);
 473                argv[argc] = p;
 474                argc++;
 475        }
 476        argv[argc] = NULL;
 477
 478        memset(&proc, 0, sizeof(proc));
 479        proc.no_stdin = 1;
 480        proc.stdout_to_stderr = 1;
 481        proc.err = use_sideband ? -1 : 0;
 482        proc.argv = argv;
 483
 484        if (!start_command(&proc)) {
 485                if (use_sideband)
 486                        copy_to_sideband(proc.err, -1, NULL);
 487                finish_command(&proc);
 488        }
 489}
 490
 491static void execute_commands(const char *unpacker_error)
 492{
 493        struct command *cmd = commands;
 494        unsigned char sha1[20];
 495
 496        if (unpacker_error) {
 497                while (cmd) {
 498                        cmd->error_string = "n/a (unpacker error)";
 499                        cmd = cmd->next;
 500                }
 501                return;
 502        }
 503
 504        if (run_receive_hook(pre_receive_hook)) {
 505                while (cmd) {
 506                        cmd->error_string = "pre-receive hook declined";
 507                        cmd = cmd->next;
 508                }
 509                return;
 510        }
 511
 512        head_name = resolve_ref("HEAD", sha1, 0, NULL);
 513
 514        while (cmd) {
 515                cmd->error_string = update(cmd);
 516                cmd = cmd->next;
 517        }
 518}
 519
 520static void read_head_info(void)
 521{
 522        struct command **p = &commands;
 523        for (;;) {
 524                static char line[1000];
 525                unsigned char old_sha1[20], new_sha1[20];
 526                struct command *cmd;
 527                char *refname;
 528                int len, reflen;
 529
 530                len = packet_read_line(0, line, sizeof(line));
 531                if (!len)
 532                        break;
 533                if (line[len-1] == '\n')
 534                        line[--len] = 0;
 535                if (len < 83 ||
 536                    line[40] != ' ' ||
 537                    line[81] != ' ' ||
 538                    get_sha1_hex(line, old_sha1) ||
 539                    get_sha1_hex(line + 41, new_sha1))
 540                        die("protocol error: expected old/new/ref, got '%s'",
 541                            line);
 542
 543                refname = line + 82;
 544                reflen = strlen(refname);
 545                if (reflen + 82 < len) {
 546                        if (strstr(refname + reflen + 1, "report-status"))
 547                                report_status = 1;
 548                        if (strstr(refname + reflen + 1, "side-band-64k"))
 549                                use_sideband = LARGE_PACKET_MAX;
 550                }
 551                cmd = xmalloc(sizeof(struct command) + len - 80);
 552                hashcpy(cmd->old_sha1, old_sha1);
 553                hashcpy(cmd->new_sha1, new_sha1);
 554                memcpy(cmd->ref_name, line + 82, len - 81);
 555                cmd->error_string = NULL;
 556                cmd->next = NULL;
 557                *p = cmd;
 558                p = &cmd->next;
 559        }
 560}
 561
 562static const char *parse_pack_header(struct pack_header *hdr)
 563{
 564        switch (read_pack_header(0, hdr)) {
 565        case PH_ERROR_EOF:
 566                return "eof before pack header was fully read";
 567
 568        case PH_ERROR_PACK_SIGNATURE:
 569                return "protocol error (pack signature mismatch detected)";
 570
 571        case PH_ERROR_PROTOCOL:
 572                return "protocol error (pack version unsupported)";
 573
 574        default:
 575                return "unknown error in parse_pack_header";
 576
 577        case 0:
 578                return NULL;
 579        }
 580}
 581
 582static const char *pack_lockfile;
 583
 584static const char *unpack(void)
 585{
 586        struct pack_header hdr;
 587        const char *hdr_err;
 588        char hdr_arg[38];
 589
 590        hdr_err = parse_pack_header(&hdr);
 591        if (hdr_err)
 592                return hdr_err;
 593        snprintf(hdr_arg, sizeof(hdr_arg),
 594                        "--pack_header=%"PRIu32",%"PRIu32,
 595                        ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
 596
 597        if (ntohl(hdr.hdr_entries) < unpack_limit) {
 598                int code, i = 0;
 599                const char *unpacker[4];
 600                unpacker[i++] = "unpack-objects";
 601                if (receive_fsck_objects)
 602                        unpacker[i++] = "--strict";
 603                unpacker[i++] = hdr_arg;
 604                unpacker[i++] = NULL;
 605                code = run_command_v_opt(unpacker, RUN_GIT_CMD);
 606                if (!code)
 607                        return NULL;
 608                return "unpack-objects abnormal exit";
 609        } else {
 610                const char *keeper[7];
 611                int s, status, i = 0;
 612                char keep_arg[256];
 613                struct child_process ip;
 614
 615                s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
 616                if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
 617                        strcpy(keep_arg + s, "localhost");
 618
 619                keeper[i++] = "index-pack";
 620                keeper[i++] = "--stdin";
 621                if (receive_fsck_objects)
 622                        keeper[i++] = "--strict";
 623                keeper[i++] = "--fix-thin";
 624                keeper[i++] = hdr_arg;
 625                keeper[i++] = keep_arg;
 626                keeper[i++] = NULL;
 627                memset(&ip, 0, sizeof(ip));
 628                ip.argv = keeper;
 629                ip.out = -1;
 630                ip.git_cmd = 1;
 631                status = start_command(&ip);
 632                if (status) {
 633                        return "index-pack fork failed";
 634                }
 635                pack_lockfile = index_pack_lockfile(ip.out);
 636                close(ip.out);
 637                status = finish_command(&ip);
 638                if (!status) {
 639                        reprepare_packed_git();
 640                        return NULL;
 641                }
 642                return "index-pack abnormal exit";
 643        }
 644}
 645
 646static void report(const char *unpack_status)
 647{
 648        struct command *cmd;
 649        struct strbuf buf = STRBUF_INIT;
 650
 651        packet_buf_write(&buf, "unpack %s\n",
 652                         unpack_status ? unpack_status : "ok");
 653        for (cmd = commands; cmd; cmd = cmd->next) {
 654                if (!cmd->error_string)
 655                        packet_buf_write(&buf, "ok %s\n",
 656                                         cmd->ref_name);
 657                else
 658                        packet_buf_write(&buf, "ng %s %s\n",
 659                                         cmd->ref_name, cmd->error_string);
 660        }
 661        packet_buf_flush(&buf);
 662
 663        if (use_sideband)
 664                send_sideband(1, 1, buf.buf, buf.len, use_sideband);
 665        else
 666                safe_write(1, buf.buf, buf.len);
 667        strbuf_release(&buf);
 668}
 669
 670static int delete_only(struct command *cmd)
 671{
 672        while (cmd) {
 673                if (!is_null_sha1(cmd->new_sha1))
 674                        return 0;
 675                cmd = cmd->next;
 676        }
 677        return 1;
 678}
 679
 680static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
 681{
 682        char *other;
 683        size_t len;
 684        struct remote *remote;
 685        struct transport *transport;
 686        const struct ref *extra;
 687
 688        e->name[-1] = '\0';
 689        other = xstrdup(make_absolute_path(e->base));
 690        e->name[-1] = '/';
 691        len = strlen(other);
 692
 693        while (other[len-1] == '/')
 694                other[--len] = '\0';
 695        if (len < 8 || memcmp(other + len - 8, "/objects", 8))
 696                return 0;
 697        /* Is this a git repository with refs? */
 698        memcpy(other + len - 8, "/refs", 6);
 699        if (!is_directory(other))
 700                return 0;
 701        other[len - 8] = '\0';
 702        remote = remote_get(other);
 703        transport = transport_get(remote, other);
 704        for (extra = transport_get_remote_refs(transport);
 705             extra;
 706             extra = extra->next) {
 707                add_extra_ref(".have", extra->old_sha1, 0);
 708        }
 709        transport_disconnect(transport);
 710        free(other);
 711        return 0;
 712}
 713
 714static void add_alternate_refs(void)
 715{
 716        foreach_alt_odb(add_refs_from_alternate, NULL);
 717}
 718
 719int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 720{
 721        int advertise_refs = 0;
 722        int stateless_rpc = 0;
 723        int i;
 724        char *dir = NULL;
 725
 726        argv++;
 727        for (i = 1; i < argc; i++) {
 728                const char *arg = *argv++;
 729
 730                if (*arg == '-') {
 731                        if (!strcmp(arg, "--advertise-refs")) {
 732                                advertise_refs = 1;
 733                                continue;
 734                        }
 735                        if (!strcmp(arg, "--stateless-rpc")) {
 736                                stateless_rpc = 1;
 737                                continue;
 738                        }
 739
 740                        usage(receive_pack_usage);
 741                }
 742                if (dir)
 743                        usage(receive_pack_usage);
 744                dir = xstrdup(arg);
 745        }
 746        if (!dir)
 747                usage(receive_pack_usage);
 748
 749        setup_path();
 750
 751        if (!enter_repo(dir, 0))
 752                die("'%s' does not appear to be a git repository", dir);
 753
 754        if (is_repository_shallow())
 755                die("attempt to push into a shallow repository");
 756
 757        git_config(receive_pack_config, NULL);
 758
 759        if (0 <= transfer_unpack_limit)
 760                unpack_limit = transfer_unpack_limit;
 761        else if (0 <= receive_unpack_limit)
 762                unpack_limit = receive_unpack_limit;
 763
 764        if (advertise_refs || !stateless_rpc) {
 765                add_alternate_refs();
 766                write_head_info();
 767                clear_extra_refs();
 768
 769                /* EOF */
 770                packet_flush(1);
 771        }
 772        if (advertise_refs)
 773                return 0;
 774
 775        read_head_info();
 776        if (commands) {
 777                const char *unpack_status = NULL;
 778
 779                if (!delete_only(commands))
 780                        unpack_status = unpack();
 781                execute_commands(unpack_status);
 782                if (pack_lockfile)
 783                        unlink_or_warn(pack_lockfile);
 784                if (report_status)
 785                        report(unpack_status);
 786                run_receive_hook(post_receive_hook);
 787                run_update_post_hook(commands);
 788                if (auto_gc) {
 789                        const char *argv_gc_auto[] = {
 790                                "gc", "--auto", "--quiet", NULL,
 791                        };
 792                        run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
 793                }
 794                if (auto_update_server_info)
 795                        update_server_info(0);
 796        }
 797        if (use_sideband)
 798                packet_flush(1);
 799        return 0;
 800}