builtin-receive-pack.con commit receive-pack: Send hook output over side band #2 (6d525d3)
   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 int copy_to_sideband(int in, int out, void *arg)
 143{
 144        char data[128];
 145        while (1) {
 146                ssize_t sz = xread(in, data, sizeof(data));
 147                if (sz <= 0)
 148                        break;
 149                send_sideband(1, 2, data, sz, use_sideband);
 150        }
 151        close(in);
 152        return 0;
 153}
 154
 155static int run_receive_hook(const char *hook_name)
 156{
 157        static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
 158        struct command *cmd;
 159        struct child_process proc;
 160        struct async muxer;
 161        const char *argv[2];
 162        int have_input = 0, code;
 163
 164        for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
 165                if (!cmd->error_string)
 166                        have_input = 1;
 167        }
 168
 169        if (!have_input || access(hook_name, X_OK) < 0)
 170                return 0;
 171
 172        argv[0] = hook_name;
 173        argv[1] = NULL;
 174
 175        memset(&proc, 0, sizeof(proc));
 176        proc.argv = argv;
 177        proc.in = -1;
 178        proc.stdout_to_stderr = 1;
 179
 180        if (use_sideband) {
 181                memset(&muxer, 0, sizeof(muxer));
 182                muxer.proc = copy_to_sideband;
 183                muxer.in = -1;
 184                code = start_async(&muxer);
 185                if (code)
 186                        return code;
 187                proc.err = muxer.in;
 188        }
 189
 190        code = start_command(&proc);
 191        if (code) {
 192                if (use_sideband)
 193                        finish_async(&muxer);
 194                return code;
 195        }
 196
 197        for (cmd = commands; cmd; cmd = cmd->next) {
 198                if (!cmd->error_string) {
 199                        size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
 200                                sha1_to_hex(cmd->old_sha1),
 201                                sha1_to_hex(cmd->new_sha1),
 202                                cmd->ref_name);
 203                        if (write_in_full(proc.in, buf, n) != n)
 204                                break;
 205                }
 206        }
 207        close(proc.in);
 208        if (use_sideband)
 209                finish_async(&muxer);
 210        return finish_command(&proc);
 211}
 212
 213static int run_update_hook(struct command *cmd)
 214{
 215        static const char update_hook[] = "hooks/update";
 216        const char *argv[5];
 217        struct child_process proc;
 218        int code;
 219
 220        if (access(update_hook, X_OK) < 0)
 221                return 0;
 222
 223        argv[0] = update_hook;
 224        argv[1] = cmd->ref_name;
 225        argv[2] = sha1_to_hex(cmd->old_sha1);
 226        argv[3] = sha1_to_hex(cmd->new_sha1);
 227        argv[4] = NULL;
 228
 229        memset(&proc, 0, sizeof(proc));
 230        proc.no_stdin = 1;
 231        proc.stdout_to_stderr = 1;
 232        proc.err = use_sideband ? -1 : 0;
 233        proc.argv = argv;
 234
 235        code = start_command(&proc);
 236        if (code)
 237                return code;
 238        if (use_sideband)
 239                copy_to_sideband(proc.err, -1, NULL);
 240        return finish_command(&proc);
 241}
 242
 243static int is_ref_checked_out(const char *ref)
 244{
 245        if (is_bare_repository())
 246                return 0;
 247
 248        if (!head_name)
 249                return 0;
 250        return !strcmp(head_name, ref);
 251}
 252
 253static char *warn_unconfigured_deny_msg[] = {
 254        "Updating the currently checked out branch may cause confusion,",
 255        "as the index and work tree do not reflect changes that are in HEAD.",
 256        "As a result, you may see the changes you just pushed into it",
 257        "reverted when you run 'git diff' over there, and you may want",
 258        "to run 'git reset --hard' before starting to work to recover.",
 259        "",
 260        "You can set 'receive.denyCurrentBranch' configuration variable to",
 261        "'refuse' in the remote repository to forbid pushing into its",
 262        "current branch."
 263        "",
 264        "To allow pushing into the current branch, you can set it to 'ignore';",
 265        "but this is not recommended unless you arranged to update its work",
 266        "tree to match what you pushed in some other way.",
 267        "",
 268        "To squelch this message, you can set it to 'warn'.",
 269        "",
 270        "Note that the default will change in a future version of git",
 271        "to refuse updating the current branch unless you have the",
 272        "configuration variable set to either 'ignore' or 'warn'."
 273};
 274
 275static void warn_unconfigured_deny(void)
 276{
 277        int i;
 278        for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
 279                warning("%s", warn_unconfigured_deny_msg[i]);
 280}
 281
 282static char *warn_unconfigured_deny_delete_current_msg[] = {
 283        "Deleting the current branch can cause confusion by making the next",
 284        "'git clone' not check out any file.",
 285        "",
 286        "You can set 'receive.denyDeleteCurrent' configuration variable to",
 287        "'refuse' in the remote repository to disallow deleting the current",
 288        "branch.",
 289        "",
 290        "You can set it to 'ignore' to allow such a delete without a warning.",
 291        "",
 292        "To make this warning message less loud, you can set it to 'warn'.",
 293        "",
 294        "Note that the default will change in a future version of git",
 295        "to refuse deleting the current branch unless you have the",
 296        "configuration variable set to either 'ignore' or 'warn'."
 297};
 298
 299static void warn_unconfigured_deny_delete_current(void)
 300{
 301        int i;
 302        for (i = 0;
 303             i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
 304             i++)
 305                warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
 306}
 307
 308static const char *update(struct command *cmd)
 309{
 310        const char *name = cmd->ref_name;
 311        unsigned char *old_sha1 = cmd->old_sha1;
 312        unsigned char *new_sha1 = cmd->new_sha1;
 313        struct ref_lock *lock;
 314
 315        /* only refs/... are allowed */
 316        if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
 317                error("refusing to create funny ref '%s' remotely", name);
 318                return "funny refname";
 319        }
 320
 321        if (is_ref_checked_out(name)) {
 322                switch (deny_current_branch) {
 323                case DENY_IGNORE:
 324                        break;
 325                case DENY_UNCONFIGURED:
 326                case DENY_WARN:
 327                        warning("updating the current branch");
 328                        if (deny_current_branch == DENY_UNCONFIGURED)
 329                                warn_unconfigured_deny();
 330                        break;
 331                case DENY_REFUSE:
 332                        error("refusing to update checked out branch: %s", name);
 333                        return "branch is currently checked out";
 334                }
 335        }
 336
 337        if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
 338                error("unpack should have generated %s, "
 339                      "but I can't find it!", sha1_to_hex(new_sha1));
 340                return "bad pack";
 341        }
 342
 343        if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
 344                if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
 345                        error("denying ref deletion for %s", name);
 346                        return "deletion prohibited";
 347                }
 348
 349                if (!strcmp(name, head_name)) {
 350                        switch (deny_delete_current) {
 351                        case DENY_IGNORE:
 352                                break;
 353                        case DENY_WARN:
 354                        case DENY_UNCONFIGURED:
 355                                if (deny_delete_current == DENY_UNCONFIGURED)
 356                                        warn_unconfigured_deny_delete_current();
 357                                warning("deleting the current branch");
 358                                break;
 359                        case DENY_REFUSE:
 360                                error("refusing to delete the current branch: %s", name);
 361                                return "deletion of the current branch prohibited";
 362                        }
 363                }
 364        }
 365
 366        if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
 367            !is_null_sha1(old_sha1) &&
 368            !prefixcmp(name, "refs/heads/")) {
 369                struct object *old_object, *new_object;
 370                struct commit *old_commit, *new_commit;
 371                struct commit_list *bases, *ent;
 372
 373                old_object = parse_object(old_sha1);
 374                new_object = parse_object(new_sha1);
 375
 376                if (!old_object || !new_object ||
 377                    old_object->type != OBJ_COMMIT ||
 378                    new_object->type != OBJ_COMMIT) {
 379                        error("bad sha1 objects for %s", name);
 380                        return "bad ref";
 381                }
 382                old_commit = (struct commit *)old_object;
 383                new_commit = (struct commit *)new_object;
 384                bases = get_merge_bases(old_commit, new_commit, 1);
 385                for (ent = bases; ent; ent = ent->next)
 386                        if (!hashcmp(old_sha1, ent->item->object.sha1))
 387                                break;
 388                free_commit_list(bases);
 389                if (!ent) {
 390                        error("denying non-fast-forward %s"
 391                              " (you should pull first)", name);
 392                        return "non-fast-forward";
 393                }
 394        }
 395        if (run_update_hook(cmd)) {
 396                error("hook declined to update %s", name);
 397                return "hook declined";
 398        }
 399
 400        if (is_null_sha1(new_sha1)) {
 401                if (!parse_object(old_sha1)) {
 402                        warning ("Allowing deletion of corrupt ref.");
 403                        old_sha1 = NULL;
 404                }
 405                if (delete_ref(name, old_sha1, 0)) {
 406                        error("failed to delete %s", name);
 407                        return "failed to delete";
 408                }
 409                return NULL; /* good */
 410        }
 411        else {
 412                lock = lock_any_ref_for_update(name, old_sha1, 0);
 413                if (!lock) {
 414                        error("failed to lock %s", name);
 415                        return "failed to lock";
 416                }
 417                if (write_ref_sha1(lock, new_sha1, "push")) {
 418                        return "failed to write"; /* error() already called */
 419                }
 420                return NULL; /* good */
 421        }
 422}
 423
 424static char update_post_hook[] = "hooks/post-update";
 425
 426static void run_update_post_hook(struct command *cmd)
 427{
 428        struct command *cmd_p;
 429        int argc;
 430        const char **argv;
 431        struct child_process proc;
 432
 433        for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
 434                if (cmd_p->error_string)
 435                        continue;
 436                argc++;
 437        }
 438        if (!argc || access(update_post_hook, X_OK) < 0)
 439                return;
 440        argv = xmalloc(sizeof(*argv) * (2 + argc));
 441        argv[0] = update_post_hook;
 442
 443        for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
 444                char *p;
 445                if (cmd_p->error_string)
 446                        continue;
 447                p = xmalloc(strlen(cmd_p->ref_name) + 1);
 448                strcpy(p, cmd_p->ref_name);
 449                argv[argc] = p;
 450                argc++;
 451        }
 452        argv[argc] = NULL;
 453
 454        memset(&proc, 0, sizeof(proc));
 455        proc.no_stdin = 1;
 456        proc.stdout_to_stderr = 1;
 457        proc.err = use_sideband ? -1 : 0;
 458        proc.argv = argv;
 459
 460        if (!start_command(&proc)) {
 461                if (use_sideband)
 462                        copy_to_sideband(proc.err, -1, NULL);
 463                finish_command(&proc);
 464        }
 465}
 466
 467static void execute_commands(const char *unpacker_error)
 468{
 469        struct command *cmd = commands;
 470        unsigned char sha1[20];
 471
 472        if (unpacker_error) {
 473                while (cmd) {
 474                        cmd->error_string = "n/a (unpacker error)";
 475                        cmd = cmd->next;
 476                }
 477                return;
 478        }
 479
 480        if (run_receive_hook(pre_receive_hook)) {
 481                while (cmd) {
 482                        cmd->error_string = "pre-receive hook declined";
 483                        cmd = cmd->next;
 484                }
 485                return;
 486        }
 487
 488        head_name = resolve_ref("HEAD", sha1, 0, NULL);
 489
 490        while (cmd) {
 491                cmd->error_string = update(cmd);
 492                cmd = cmd->next;
 493        }
 494}
 495
 496static void read_head_info(void)
 497{
 498        struct command **p = &commands;
 499        for (;;) {
 500                static char line[1000];
 501                unsigned char old_sha1[20], new_sha1[20];
 502                struct command *cmd;
 503                char *refname;
 504                int len, reflen;
 505
 506                len = packet_read_line(0, line, sizeof(line));
 507                if (!len)
 508                        break;
 509                if (line[len-1] == '\n')
 510                        line[--len] = 0;
 511                if (len < 83 ||
 512                    line[40] != ' ' ||
 513                    line[81] != ' ' ||
 514                    get_sha1_hex(line, old_sha1) ||
 515                    get_sha1_hex(line + 41, new_sha1))
 516                        die("protocol error: expected old/new/ref, got '%s'",
 517                            line);
 518
 519                refname = line + 82;
 520                reflen = strlen(refname);
 521                if (reflen + 82 < len) {
 522                        if (strstr(refname + reflen + 1, "report-status"))
 523                                report_status = 1;
 524                        if (strstr(refname + reflen + 1, "side-band-64k"))
 525                                use_sideband = LARGE_PACKET_MAX;
 526                }
 527                cmd = xmalloc(sizeof(struct command) + len - 80);
 528                hashcpy(cmd->old_sha1, old_sha1);
 529                hashcpy(cmd->new_sha1, new_sha1);
 530                memcpy(cmd->ref_name, line + 82, len - 81);
 531                cmd->error_string = NULL;
 532                cmd->next = NULL;
 533                *p = cmd;
 534                p = &cmd->next;
 535        }
 536}
 537
 538static const char *parse_pack_header(struct pack_header *hdr)
 539{
 540        switch (read_pack_header(0, hdr)) {
 541        case PH_ERROR_EOF:
 542                return "eof before pack header was fully read";
 543
 544        case PH_ERROR_PACK_SIGNATURE:
 545                return "protocol error (pack signature mismatch detected)";
 546
 547        case PH_ERROR_PROTOCOL:
 548                return "protocol error (pack version unsupported)";
 549
 550        default:
 551                return "unknown error in parse_pack_header";
 552
 553        case 0:
 554                return NULL;
 555        }
 556}
 557
 558static const char *pack_lockfile;
 559
 560static const char *unpack(void)
 561{
 562        struct pack_header hdr;
 563        const char *hdr_err;
 564        char hdr_arg[38];
 565
 566        hdr_err = parse_pack_header(&hdr);
 567        if (hdr_err)
 568                return hdr_err;
 569        snprintf(hdr_arg, sizeof(hdr_arg),
 570                        "--pack_header=%"PRIu32",%"PRIu32,
 571                        ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
 572
 573        if (ntohl(hdr.hdr_entries) < unpack_limit) {
 574                int code, i = 0;
 575                const char *unpacker[4];
 576                unpacker[i++] = "unpack-objects";
 577                if (receive_fsck_objects)
 578                        unpacker[i++] = "--strict";
 579                unpacker[i++] = hdr_arg;
 580                unpacker[i++] = NULL;
 581                code = run_command_v_opt(unpacker, RUN_GIT_CMD);
 582                if (!code)
 583                        return NULL;
 584                return "unpack-objects abnormal exit";
 585        } else {
 586                const char *keeper[7];
 587                int s, status, i = 0;
 588                char keep_arg[256];
 589                struct child_process ip;
 590
 591                s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
 592                if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
 593                        strcpy(keep_arg + s, "localhost");
 594
 595                keeper[i++] = "index-pack";
 596                keeper[i++] = "--stdin";
 597                if (receive_fsck_objects)
 598                        keeper[i++] = "--strict";
 599                keeper[i++] = "--fix-thin";
 600                keeper[i++] = hdr_arg;
 601                keeper[i++] = keep_arg;
 602                keeper[i++] = NULL;
 603                memset(&ip, 0, sizeof(ip));
 604                ip.argv = keeper;
 605                ip.out = -1;
 606                ip.git_cmd = 1;
 607                status = start_command(&ip);
 608                if (status) {
 609                        return "index-pack fork failed";
 610                }
 611                pack_lockfile = index_pack_lockfile(ip.out);
 612                close(ip.out);
 613                status = finish_command(&ip);
 614                if (!status) {
 615                        reprepare_packed_git();
 616                        return NULL;
 617                }
 618                return "index-pack abnormal exit";
 619        }
 620}
 621
 622static void report(const char *unpack_status)
 623{
 624        struct command *cmd;
 625        struct strbuf buf = STRBUF_INIT;
 626
 627        packet_buf_write(&buf, "unpack %s\n",
 628                         unpack_status ? unpack_status : "ok");
 629        for (cmd = commands; cmd; cmd = cmd->next) {
 630                if (!cmd->error_string)
 631                        packet_buf_write(&buf, "ok %s\n",
 632                                         cmd->ref_name);
 633                else
 634                        packet_buf_write(&buf, "ng %s %s\n",
 635                                         cmd->ref_name, cmd->error_string);
 636        }
 637        packet_buf_flush(&buf);
 638
 639        if (use_sideband)
 640                send_sideband(1, 1, buf.buf, buf.len, use_sideband);
 641        else
 642                safe_write(1, buf.buf, buf.len);
 643        strbuf_release(&buf);
 644}
 645
 646static int delete_only(struct command *cmd)
 647{
 648        while (cmd) {
 649                if (!is_null_sha1(cmd->new_sha1))
 650                        return 0;
 651                cmd = cmd->next;
 652        }
 653        return 1;
 654}
 655
 656static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
 657{
 658        char *other;
 659        size_t len;
 660        struct remote *remote;
 661        struct transport *transport;
 662        const struct ref *extra;
 663
 664        e->name[-1] = '\0';
 665        other = xstrdup(make_absolute_path(e->base));
 666        e->name[-1] = '/';
 667        len = strlen(other);
 668
 669        while (other[len-1] == '/')
 670                other[--len] = '\0';
 671        if (len < 8 || memcmp(other + len - 8, "/objects", 8))
 672                return 0;
 673        /* Is this a git repository with refs? */
 674        memcpy(other + len - 8, "/refs", 6);
 675        if (!is_directory(other))
 676                return 0;
 677        other[len - 8] = '\0';
 678        remote = remote_get(other);
 679        transport = transport_get(remote, other);
 680        for (extra = transport_get_remote_refs(transport);
 681             extra;
 682             extra = extra->next) {
 683                add_extra_ref(".have", extra->old_sha1, 0);
 684        }
 685        transport_disconnect(transport);
 686        free(other);
 687        return 0;
 688}
 689
 690static void add_alternate_refs(void)
 691{
 692        foreach_alt_odb(add_refs_from_alternate, NULL);
 693}
 694
 695int cmd_receive_pack(int argc, const char **argv, const char *prefix)
 696{
 697        int advertise_refs = 0;
 698        int stateless_rpc = 0;
 699        int i;
 700        char *dir = NULL;
 701
 702        argv++;
 703        for (i = 1; i < argc; i++) {
 704                const char *arg = *argv++;
 705
 706                if (*arg == '-') {
 707                        if (!strcmp(arg, "--advertise-refs")) {
 708                                advertise_refs = 1;
 709                                continue;
 710                        }
 711                        if (!strcmp(arg, "--stateless-rpc")) {
 712                                stateless_rpc = 1;
 713                                continue;
 714                        }
 715
 716                        usage(receive_pack_usage);
 717                }
 718                if (dir)
 719                        usage(receive_pack_usage);
 720                dir = xstrdup(arg);
 721        }
 722        if (!dir)
 723                usage(receive_pack_usage);
 724
 725        setup_path();
 726
 727        if (!enter_repo(dir, 0))
 728                die("'%s' does not appear to be a git repository", dir);
 729
 730        if (is_repository_shallow())
 731                die("attempt to push into a shallow repository");
 732
 733        git_config(receive_pack_config, NULL);
 734
 735        if (0 <= transfer_unpack_limit)
 736                unpack_limit = transfer_unpack_limit;
 737        else if (0 <= receive_unpack_limit)
 738                unpack_limit = receive_unpack_limit;
 739
 740        if (advertise_refs || !stateless_rpc) {
 741                add_alternate_refs();
 742                write_head_info();
 743                clear_extra_refs();
 744
 745                /* EOF */
 746                packet_flush(1);
 747        }
 748        if (advertise_refs)
 749                return 0;
 750
 751        read_head_info();
 752        if (commands) {
 753                const char *unpack_status = NULL;
 754
 755                if (!delete_only(commands))
 756                        unpack_status = unpack();
 757                execute_commands(unpack_status);
 758                if (pack_lockfile)
 759                        unlink_or_warn(pack_lockfile);
 760                if (report_status)
 761                        report(unpack_status);
 762                run_receive_hook(post_receive_hook);
 763                run_update_post_hook(commands);
 764                if (auto_gc) {
 765                        const char *argv_gc_auto[] = {
 766                                "gc", "--auto", "--quiet", NULL,
 767                        };
 768                        run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
 769                }
 770                if (auto_update_server_info)
 771                        update_server_info(0);
 772        }
 773        if (use_sideband)
 774                packet_flush(1);
 775        return 0;
 776}