builtin / push.con commit fetch: convert prune_refs to take a struct refspec (def11e7)
   1/*
   2 * "git push"
   3 */
   4#include "cache.h"
   5#include "config.h"
   6#include "refs.h"
   7#include "refspec.h"
   8#include "run-command.h"
   9#include "builtin.h"
  10#include "remote.h"
  11#include "transport.h"
  12#include "parse-options.h"
  13#include "submodule.h"
  14#include "submodule-config.h"
  15#include "send-pack.h"
  16#include "color.h"
  17
  18static const char * const push_usage[] = {
  19        N_("git push [<options>] [<repository> [<refspec>...]]"),
  20        NULL,
  21};
  22
  23static int push_use_color = -1;
  24static char push_colors[][COLOR_MAXLEN] = {
  25        GIT_COLOR_RESET,
  26        GIT_COLOR_RED,  /* ERROR */
  27};
  28
  29enum color_push {
  30        PUSH_COLOR_RESET = 0,
  31        PUSH_COLOR_ERROR = 1
  32};
  33
  34static int parse_push_color_slot(const char *slot)
  35{
  36        if (!strcasecmp(slot, "reset"))
  37                return PUSH_COLOR_RESET;
  38        if (!strcasecmp(slot, "error"))
  39                return PUSH_COLOR_ERROR;
  40        return -1;
  41}
  42
  43static const char *push_get_color(enum color_push ix)
  44{
  45        if (want_color_stderr(push_use_color))
  46                return push_colors[ix];
  47        return "";
  48}
  49
  50static int thin = 1;
  51static int deleterefs;
  52static const char *receivepack;
  53static int verbosity;
  54static int progress = -1;
  55static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
  56static enum transport_family family;
  57
  58static struct push_cas_option cas;
  59
  60static const char **refspec;
  61static int refspec_nr;
  62static int refspec_alloc;
  63
  64static struct string_list push_options_config = STRING_LIST_INIT_DUP;
  65
  66static void add_refspec(const char *ref)
  67{
  68        refspec_nr++;
  69        ALLOC_GROW(refspec, refspec_nr, refspec_alloc);
  70        refspec[refspec_nr-1] = ref;
  71}
  72
  73static const char *map_refspec(const char *ref,
  74                               struct remote *remote, struct ref *local_refs)
  75{
  76        struct ref *matched = NULL;
  77
  78        /* Does "ref" uniquely name our ref? */
  79        if (count_refspec_match(ref, local_refs, &matched) != 1)
  80                return ref;
  81
  82        if (remote->push.nr) {
  83                struct refspec_item query;
  84                memset(&query, 0, sizeof(struct refspec_item));
  85                query.src = matched->name;
  86                if (!query_refspecs(remote->push.items, remote->push.nr, &query) &&
  87                    query.dst) {
  88                        struct strbuf buf = STRBUF_INIT;
  89                        strbuf_addf(&buf, "%s%s:%s",
  90                                    query.force ? "+" : "",
  91                                    query.src, query.dst);
  92                        return strbuf_detach(&buf, NULL);
  93                }
  94        }
  95
  96        if (push_default == PUSH_DEFAULT_UPSTREAM &&
  97            starts_with(matched->name, "refs/heads/")) {
  98                struct branch *branch = branch_get(matched->name + 11);
  99                if (branch->merge_nr == 1 && branch->merge[0]->src) {
 100                        struct strbuf buf = STRBUF_INIT;
 101                        strbuf_addf(&buf, "%s:%s",
 102                                    ref, branch->merge[0]->src);
 103                        return strbuf_detach(&buf, NULL);
 104                }
 105        }
 106
 107        return ref;
 108}
 109
 110static void set_refspecs(const char **refs, int nr, const char *repo)
 111{
 112        struct remote *remote = NULL;
 113        struct ref *local_refs = NULL;
 114        int i;
 115
 116        for (i = 0; i < nr; i++) {
 117                const char *ref = refs[i];
 118                if (!strcmp("tag", ref)) {
 119                        struct strbuf tagref = STRBUF_INIT;
 120                        if (nr <= ++i)
 121                                die(_("tag shorthand without <tag>"));
 122                        ref = refs[i];
 123                        if (deleterefs)
 124                                strbuf_addf(&tagref, ":refs/tags/%s", ref);
 125                        else
 126                                strbuf_addf(&tagref, "refs/tags/%s", ref);
 127                        ref = strbuf_detach(&tagref, NULL);
 128                } else if (deleterefs) {
 129                        struct strbuf delref = STRBUF_INIT;
 130                        if (strchr(ref, ':'))
 131                                die(_("--delete only accepts plain target ref names"));
 132                        strbuf_addf(&delref, ":%s", ref);
 133                        ref = strbuf_detach(&delref, NULL);
 134                } else if (!strchr(ref, ':')) {
 135                        if (!remote) {
 136                                /* lazily grab remote and local_refs */
 137                                remote = remote_get(repo);
 138                                local_refs = get_local_heads();
 139                        }
 140                        ref = map_refspec(ref, remote, local_refs);
 141                }
 142                add_refspec(ref);
 143        }
 144}
 145
 146static int push_url_of_remote(struct remote *remote, const char ***url_p)
 147{
 148        if (remote->pushurl_nr) {
 149                *url_p = remote->pushurl;
 150                return remote->pushurl_nr;
 151        }
 152        *url_p = remote->url;
 153        return remote->url_nr;
 154}
 155
 156static NORETURN int die_push_simple(struct branch *branch, struct remote *remote) {
 157        /*
 158         * There's no point in using shorten_unambiguous_ref here,
 159         * as the ambiguity would be on the remote side, not what
 160         * we have locally. Plus, this is supposed to be the simple
 161         * mode. If the user is doing something crazy like setting
 162         * upstream to a non-branch, we should probably be showing
 163         * them the big ugly fully qualified ref.
 164         */
 165        const char *advice_maybe = "";
 166        const char *short_upstream = branch->merge[0]->src;
 167
 168        skip_prefix(short_upstream, "refs/heads/", &short_upstream);
 169
 170        /*
 171         * Don't show advice for people who explicitly set
 172         * push.default.
 173         */
 174        if (push_default == PUSH_DEFAULT_UNSPECIFIED)
 175                advice_maybe = _("\n"
 176                                 "To choose either option permanently, "
 177                                 "see push.default in 'git help config'.");
 178        die(_("The upstream branch of your current branch does not match\n"
 179              "the name of your current branch.  To push to the upstream branch\n"
 180              "on the remote, use\n"
 181              "\n"
 182              "    git push %s HEAD:%s\n"
 183              "\n"
 184              "To push to the branch of the same name on the remote, use\n"
 185              "\n"
 186              "    git push %s %s\n"
 187              "%s"),
 188            remote->name, short_upstream,
 189            remote->name, branch->name, advice_maybe);
 190}
 191
 192static const char message_detached_head_die[] =
 193        N_("You are not currently on a branch.\n"
 194           "To push the history leading to the current (detached HEAD)\n"
 195           "state now, use\n"
 196           "\n"
 197           "    git push %s HEAD:<name-of-remote-branch>\n");
 198
 199static void setup_push_upstream(struct remote *remote, struct branch *branch,
 200                                int triangular, int simple)
 201{
 202        struct strbuf refspec = STRBUF_INIT;
 203
 204        if (!branch)
 205                die(_(message_detached_head_die), remote->name);
 206        if (!branch->merge_nr || !branch->merge || !branch->remote_name)
 207                die(_("The current branch %s has no upstream branch.\n"
 208                    "To push the current branch and set the remote as upstream, use\n"
 209                    "\n"
 210                    "    git push --set-upstream %s %s\n"),
 211                    branch->name,
 212                    remote->name,
 213                    branch->name);
 214        if (branch->merge_nr != 1)
 215                die(_("The current branch %s has multiple upstream branches, "
 216                    "refusing to push."), branch->name);
 217        if (triangular)
 218                die(_("You are pushing to remote '%s', which is not the upstream of\n"
 219                      "your current branch '%s', without telling me what to push\n"
 220                      "to update which remote branch."),
 221                    remote->name, branch->name);
 222
 223        if (simple) {
 224                /* Additional safety */
 225                if (strcmp(branch->refname, branch->merge[0]->src))
 226                        die_push_simple(branch, remote);
 227        }
 228
 229        strbuf_addf(&refspec, "%s:%s", branch->refname, branch->merge[0]->src);
 230        add_refspec(refspec.buf);
 231}
 232
 233static void setup_push_current(struct remote *remote, struct branch *branch)
 234{
 235        struct strbuf refspec = STRBUF_INIT;
 236
 237        if (!branch)
 238                die(_(message_detached_head_die), remote->name);
 239        strbuf_addf(&refspec, "%s:%s", branch->refname, branch->refname);
 240        add_refspec(refspec.buf);
 241}
 242
 243static int is_workflow_triangular(struct remote *remote)
 244{
 245        struct remote *fetch_remote = remote_get(NULL);
 246        return (fetch_remote && fetch_remote != remote);
 247}
 248
 249static void setup_default_push_refspecs(struct remote *remote)
 250{
 251        struct branch *branch = branch_get(NULL);
 252        int triangular = is_workflow_triangular(remote);
 253
 254        switch (push_default) {
 255        default:
 256        case PUSH_DEFAULT_MATCHING:
 257                add_refspec(":");
 258                break;
 259
 260        case PUSH_DEFAULT_UNSPECIFIED:
 261        case PUSH_DEFAULT_SIMPLE:
 262                if (triangular)
 263                        setup_push_current(remote, branch);
 264                else
 265                        setup_push_upstream(remote, branch, triangular, 1);
 266                break;
 267
 268        case PUSH_DEFAULT_UPSTREAM:
 269                setup_push_upstream(remote, branch, triangular, 0);
 270                break;
 271
 272        case PUSH_DEFAULT_CURRENT:
 273                setup_push_current(remote, branch);
 274                break;
 275
 276        case PUSH_DEFAULT_NOTHING:
 277                die(_("You didn't specify any refspecs to push, and "
 278                    "push.default is \"nothing\"."));
 279                break;
 280        }
 281}
 282
 283static const char message_advice_pull_before_push[] =
 284        N_("Updates were rejected because the tip of your current branch is behind\n"
 285           "its remote counterpart. Integrate the remote changes (e.g.\n"
 286           "'git pull ...') before pushing again.\n"
 287           "See the 'Note about fast-forwards' in 'git push --help' for details.");
 288
 289static const char message_advice_checkout_pull_push[] =
 290        N_("Updates were rejected because a pushed branch tip is behind its remote\n"
 291           "counterpart. Check out this branch and integrate the remote changes\n"
 292           "(e.g. 'git pull ...') before pushing again.\n"
 293           "See the 'Note about fast-forwards' in 'git push --help' for details.");
 294
 295static const char message_advice_ref_fetch_first[] =
 296        N_("Updates were rejected because the remote contains work that you do\n"
 297           "not have locally. This is usually caused by another repository pushing\n"
 298           "to the same ref. You may want to first integrate the remote changes\n"
 299           "(e.g., 'git pull ...') before pushing again.\n"
 300           "See the 'Note about fast-forwards' in 'git push --help' for details.");
 301
 302static const char message_advice_ref_already_exists[] =
 303        N_("Updates were rejected because the tag already exists in the remote.");
 304
 305static const char message_advice_ref_needs_force[] =
 306        N_("You cannot update a remote ref that points at a non-commit object,\n"
 307           "or update a remote ref to make it point at a non-commit object,\n"
 308           "without using the '--force' option.\n");
 309
 310static void advise_pull_before_push(void)
 311{
 312        if (!advice_push_non_ff_current || !advice_push_update_rejected)
 313                return;
 314        advise(_(message_advice_pull_before_push));
 315}
 316
 317static void advise_checkout_pull_push(void)
 318{
 319        if (!advice_push_non_ff_matching || !advice_push_update_rejected)
 320                return;
 321        advise(_(message_advice_checkout_pull_push));
 322}
 323
 324static void advise_ref_already_exists(void)
 325{
 326        if (!advice_push_already_exists || !advice_push_update_rejected)
 327                return;
 328        advise(_(message_advice_ref_already_exists));
 329}
 330
 331static void advise_ref_fetch_first(void)
 332{
 333        if (!advice_push_fetch_first || !advice_push_update_rejected)
 334                return;
 335        advise(_(message_advice_ref_fetch_first));
 336}
 337
 338static void advise_ref_needs_force(void)
 339{
 340        if (!advice_push_needs_force || !advice_push_update_rejected)
 341                return;
 342        advise(_(message_advice_ref_needs_force));
 343}
 344
 345static int push_with_options(struct transport *transport, int flags)
 346{
 347        int err;
 348        unsigned int reject_reasons;
 349
 350        transport_set_verbosity(transport, verbosity, progress);
 351        transport->family = family;
 352
 353        if (receivepack)
 354                transport_set_option(transport,
 355                                     TRANS_OPT_RECEIVEPACK, receivepack);
 356        transport_set_option(transport, TRANS_OPT_THIN, thin ? "yes" : NULL);
 357
 358        if (!is_empty_cas(&cas)) {
 359                if (!transport->smart_options)
 360                        die("underlying transport does not support --%s option",
 361                            CAS_OPT_NAME);
 362                transport->smart_options->cas = &cas;
 363        }
 364
 365        if (verbosity > 0)
 366                fprintf(stderr, _("Pushing to %s\n"), transport->url);
 367        err = transport_push(transport, refspec_nr, refspec, flags,
 368                             &reject_reasons);
 369        if (err != 0) {
 370                fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR));
 371                error(_("failed to push some refs to '%s'"), transport->url);
 372                fprintf(stderr, "%s", push_get_color(PUSH_COLOR_RESET));
 373        }
 374
 375        err |= transport_disconnect(transport);
 376        if (!err)
 377                return 0;
 378
 379        if (reject_reasons & REJECT_NON_FF_HEAD) {
 380                advise_pull_before_push();
 381        } else if (reject_reasons & REJECT_NON_FF_OTHER) {
 382                advise_checkout_pull_push();
 383        } else if (reject_reasons & REJECT_ALREADY_EXISTS) {
 384                advise_ref_already_exists();
 385        } else if (reject_reasons & REJECT_FETCH_FIRST) {
 386                advise_ref_fetch_first();
 387        } else if (reject_reasons & REJECT_NEEDS_FORCE) {
 388                advise_ref_needs_force();
 389        }
 390
 391        return 1;
 392}
 393
 394static int do_push(const char *repo, int flags,
 395                   const struct string_list *push_options)
 396{
 397        int i, errs;
 398        struct remote *remote = pushremote_get(repo);
 399        const char **url;
 400        int url_nr;
 401
 402        if (!remote) {
 403                if (repo)
 404                        die(_("bad repository '%s'"), repo);
 405                die(_("No configured push destination.\n"
 406                    "Either specify the URL from the command-line or configure a remote repository using\n"
 407                    "\n"
 408                    "    git remote add <name> <url>\n"
 409                    "\n"
 410                    "and then push using the remote name\n"
 411                    "\n"
 412                    "    git push <name>\n"));
 413        }
 414
 415        if (remote->mirror)
 416                flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
 417
 418        if (push_options->nr)
 419                flags |= TRANSPORT_PUSH_OPTIONS;
 420
 421        if ((flags & TRANSPORT_PUSH_ALL) && refspec) {
 422                if (!strcmp(*refspec, "refs/tags/*"))
 423                        return error(_("--all and --tags are incompatible"));
 424                return error(_("--all can't be combined with refspecs"));
 425        }
 426
 427        if ((flags & TRANSPORT_PUSH_MIRROR) && refspec) {
 428                if (!strcmp(*refspec, "refs/tags/*"))
 429                        return error(_("--mirror and --tags are incompatible"));
 430                return error(_("--mirror can't be combined with refspecs"));
 431        }
 432
 433        if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
 434                                (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
 435                return error(_("--all and --mirror are incompatible"));
 436        }
 437
 438        if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
 439                if (remote->push.raw_nr) {
 440                        refspec = remote->push.raw;
 441                        refspec_nr = remote->push.raw_nr;
 442                } else if (!(flags & TRANSPORT_PUSH_MIRROR))
 443                        setup_default_push_refspecs(remote);
 444        }
 445        errs = 0;
 446        url_nr = push_url_of_remote(remote, &url);
 447        if (url_nr) {
 448                for (i = 0; i < url_nr; i++) {
 449                        struct transport *transport =
 450                                transport_get(remote, url[i]);
 451                        if (flags & TRANSPORT_PUSH_OPTIONS)
 452                                transport->push_options = push_options;
 453                        if (push_with_options(transport, flags))
 454                                errs++;
 455                }
 456        } else {
 457                struct transport *transport =
 458                        transport_get(remote, NULL);
 459                if (flags & TRANSPORT_PUSH_OPTIONS)
 460                        transport->push_options = push_options;
 461                if (push_with_options(transport, flags))
 462                        errs++;
 463        }
 464        return !!errs;
 465}
 466
 467static int option_parse_recurse_submodules(const struct option *opt,
 468                                   const char *arg, int unset)
 469{
 470        int *recurse_submodules = opt->value;
 471
 472        if (unset)
 473                *recurse_submodules = RECURSE_SUBMODULES_OFF;
 474        else if (arg)
 475                *recurse_submodules = parse_push_recurse_submodules_arg(opt->long_name, arg);
 476        else
 477                die("%s missing parameter", opt->long_name);
 478
 479        return 0;
 480}
 481
 482static void set_push_cert_flags(int *flags, int v)
 483{
 484        switch (v) {
 485        case SEND_PACK_PUSH_CERT_NEVER:
 486                *flags &= ~(TRANSPORT_PUSH_CERT_ALWAYS | TRANSPORT_PUSH_CERT_IF_ASKED);
 487                break;
 488        case SEND_PACK_PUSH_CERT_ALWAYS:
 489                *flags |= TRANSPORT_PUSH_CERT_ALWAYS;
 490                *flags &= ~TRANSPORT_PUSH_CERT_IF_ASKED;
 491                break;
 492        case SEND_PACK_PUSH_CERT_IF_ASKED:
 493                *flags |= TRANSPORT_PUSH_CERT_IF_ASKED;
 494                *flags &= ~TRANSPORT_PUSH_CERT_ALWAYS;
 495                break;
 496        }
 497}
 498
 499
 500static int git_push_config(const char *k, const char *v, void *cb)
 501{
 502        const char *slot_name;
 503        int *flags = cb;
 504        int status;
 505
 506        status = git_gpg_config(k, v, NULL);
 507        if (status)
 508                return status;
 509
 510        if (!strcmp(k, "push.followtags")) {
 511                if (git_config_bool(k, v))
 512                        *flags |= TRANSPORT_PUSH_FOLLOW_TAGS;
 513                else
 514                        *flags &= ~TRANSPORT_PUSH_FOLLOW_TAGS;
 515                return 0;
 516        } else if (!strcmp(k, "push.gpgsign")) {
 517                const char *value;
 518                if (!git_config_get_value("push.gpgsign", &value)) {
 519                        switch (git_parse_maybe_bool(value)) {
 520                        case 0:
 521                                set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_NEVER);
 522                                break;
 523                        case 1:
 524                                set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_ALWAYS);
 525                                break;
 526                        default:
 527                                if (value && !strcasecmp(value, "if-asked"))
 528                                        set_push_cert_flags(flags, SEND_PACK_PUSH_CERT_IF_ASKED);
 529                                else
 530                                        return error("Invalid value for '%s'", k);
 531                        }
 532                }
 533        } else if (!strcmp(k, "push.recursesubmodules")) {
 534                const char *value;
 535                if (!git_config_get_value("push.recursesubmodules", &value))
 536                        recurse_submodules = parse_push_recurse_submodules_arg(k, value);
 537        } else if (!strcmp(k, "submodule.recurse")) {
 538                int val = git_config_bool(k, v) ?
 539                        RECURSE_SUBMODULES_ON_DEMAND : RECURSE_SUBMODULES_OFF;
 540                recurse_submodules = val;
 541        } else if (!strcmp(k, "push.pushoption")) {
 542                if (!v)
 543                        return config_error_nonbool(k);
 544                else
 545                        if (!*v)
 546                                string_list_clear(&push_options_config, 0);
 547                        else
 548                                string_list_append(&push_options_config, v);
 549                return 0;
 550        } else if (!strcmp(k, "color.push")) {
 551                push_use_color = git_config_colorbool(k, v);
 552                return 0;
 553        } else if (skip_prefix(k, "color.push.", &slot_name)) {
 554                int slot = parse_push_color_slot(slot_name);
 555                if (slot < 0)
 556                        return 0;
 557                if (!v)
 558                        return config_error_nonbool(k);
 559                return color_parse(v, push_colors[slot]);
 560        }
 561
 562        return git_default_config(k, v, NULL);
 563}
 564
 565int cmd_push(int argc, const char **argv, const char *prefix)
 566{
 567        int flags = 0;
 568        int tags = 0;
 569        int push_cert = -1;
 570        int rc;
 571        const char *repo = NULL;        /* default repository */
 572        struct string_list push_options_cmdline = STRING_LIST_INIT_DUP;
 573        struct string_list *push_options;
 574        const struct string_list_item *item;
 575
 576        struct option options[] = {
 577                OPT__VERBOSITY(&verbosity),
 578                OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
 579                OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL),
 580                OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"),
 581                            (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
 582                OPT_BOOL('d', "delete", &deleterefs, N_("delete refs")),
 583                OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")),
 584                OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN),
 585                OPT_BIT( 0,  "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN),
 586                OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE),
 587                { OPTION_CALLBACK,
 588                  0, CAS_OPT_NAME, &cas, N_("refname>:<expect"),
 589                  N_("require old value of ref to be at this value"),
 590                  PARSE_OPT_OPTARG, parseopt_push_cas_option },
 591                { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules, "check|on-demand|no",
 592                        N_("control recursive pushing of submodules"),
 593                        PARSE_OPT_OPTARG, option_parse_recurse_submodules },
 594                OPT_BOOL_F( 0 , "thin", &thin, N_("use thin pack"), PARSE_OPT_NOCOMPLETE),
 595                OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", N_("receive pack program")),
 596                OPT_STRING( 0 , "exec", &receivepack, "receive-pack", N_("receive pack program")),
 597                OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git pull/status"),
 598                        TRANSPORT_PUSH_SET_UPSTREAM),
 599                OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
 600                OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"),
 601                        TRANSPORT_PUSH_PRUNE),
 602                OPT_BIT(0, "no-verify", &flags, N_("bypass pre-push hook"), TRANSPORT_PUSH_NO_HOOK),
 603                OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"),
 604                        TRANSPORT_PUSH_FOLLOW_TAGS),
 605                { OPTION_CALLBACK,
 606                  0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
 607                  PARSE_OPT_OPTARG, option_parse_push_signed },
 608                OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
 609                OPT_STRING_LIST('o', "push-option", &push_options_cmdline, N_("server-specific"), N_("option to transmit")),
 610                OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
 611                                TRANSPORT_FAMILY_IPV4),
 612                OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
 613                                TRANSPORT_FAMILY_IPV6),
 614                OPT_END()
 615        };
 616
 617        packet_trace_identity("push");
 618        git_config(git_push_config, &flags);
 619        argc = parse_options(argc, argv, prefix, options, push_usage, 0);
 620        push_options = (push_options_cmdline.nr
 621                ? &push_options_cmdline
 622                : &push_options_config);
 623        set_push_cert_flags(&flags, push_cert);
 624
 625        if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR))))
 626                die(_("--delete is incompatible with --all, --mirror and --tags"));
 627        if (deleterefs && argc < 2)
 628                die(_("--delete doesn't make sense without any refs"));
 629
 630        if (recurse_submodules == RECURSE_SUBMODULES_CHECK)
 631                flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
 632        else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
 633                flags |= TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND;
 634        else if (recurse_submodules == RECURSE_SUBMODULES_ONLY)
 635                flags |= TRANSPORT_RECURSE_SUBMODULES_ONLY;
 636
 637        if (tags)
 638                add_refspec("refs/tags/*");
 639
 640        if (argc > 0) {
 641                repo = argv[0];
 642                set_refspecs(argv + 1, argc - 1, repo);
 643        }
 644
 645        for_each_string_list_item(item, push_options)
 646                if (strchr(item->string, '\n'))
 647                        die(_("push options must not have new line characters"));
 648
 649        rc = do_push(repo, flags, push_options);
 650        string_list_clear(&push_options_cmdline, 0);
 651        string_list_clear(&push_options_config, 0);
 652        if (rc == -1)
 653                usage_with_options(push_usage, options);
 654        else
 655                return rc;
 656}