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