diff: use tempfile module
[gitweb.git] / builtin / push.c
index 3dd160c6b6a9a6af5010163f86b8a1ac2095dee1..57c138bd7bc972bfa337de4c615cbfffb99ecc71 100644 (file)
@@ -58,7 +58,7 @@ static const char *map_refspec(const char *ref,
        }
 
        if (push_default == PUSH_DEFAULT_UPSTREAM &&
-           !prefixcmp(matched->name, "refs/heads/")) {
+           starts_with(matched->name, "refs/heads/")) {
                struct branch *branch = branch_get(matched->name + 11);
                if (branch->merge_nr == 1 && branch->merge[0]->src) {
                        struct strbuf buf = STRBUF_INIT;
@@ -127,11 +127,10 @@ static NORETURN int die_push_simple(struct branch *branch, struct remote *remote
         * them the big ugly fully qualified ref.
         */
        const char *advice_maybe = "";
-       const char *short_upstream =
-               skip_prefix(branch->merge[0]->src, "refs/heads/");
+       const char *short_upstream = branch->merge[0]->src;
+
+       skip_prefix(short_upstream, "refs/heads/", &short_upstream);
 
-       if (!short_upstream)
-               short_upstream = branch->merge[0]->src;
        /*
         * Don't show advice for people who explicitly set
         * push.default.
@@ -162,7 +161,7 @@ static const char message_detached_head_die[] =
           "    git push %s HEAD:<name-of-remote-branch>\n");
 
 static void setup_push_upstream(struct remote *remote, struct branch *branch,
-                               int triangular)
+                               int triangular, int simple)
 {
        struct strbuf refspec = STRBUF_INIT;
 
@@ -185,7 +184,7 @@ static void setup_push_upstream(struct remote *remote, struct branch *branch,
                      "to update which remote branch."),
                    remote->name, branch->name);
 
-       if (push_default == PUSH_DEFAULT_SIMPLE) {
+       if (simple) {
                /* Additional safety */
                if (strcmp(branch->refname, branch->merge[0]->src))
                        die_push_simple(branch, remote);
@@ -216,7 +215,7 @@ N_("push.default is unset; its implicit value has changed in\n"
    "When push.default is set to 'matching', git will push local branches\n"
    "to the remote branches that already exist with the same name.\n"
    "\n"
-   "In Git 2.0, Git will default to the more conservative 'simple'\n"
+   "Since Git 2.0, Git defaults to the more conservative 'simple'\n"
    "behavior, which only pushes the current branch to the corresponding\n"
    "remote branch that 'git pull' uses to update the current branch.\n"
    "\n"
@@ -258,11 +257,11 @@ static void setup_default_push_refspecs(struct remote *remote)
                if (triangular)
                        setup_push_current(remote, branch);
                else
-                       setup_push_upstream(remote, branch, triangular);
+                       setup_push_upstream(remote, branch, triangular, 1);
                break;
 
        case PUSH_DEFAULT_UPSTREAM:
-               setup_push_upstream(remote, branch, triangular);
+               setup_push_upstream(remote, branch, triangular, 0);
                break;
 
        case PUSH_DEFAULT_CURRENT:
@@ -472,6 +471,26 @@ static int option_parse_recurse_submodules(const struct option *opt,
        return 0;
 }
 
+static int git_push_config(const char *k, const char *v, void *cb)
+{
+       int *flags = cb;
+       int status;
+
+       status = git_gpg_config(k, v, NULL);
+       if (status)
+               return status;
+
+       if (!strcmp(k, "push.followtags")) {
+               if (git_config_bool(k, v))
+                       *flags |= TRANSPORT_PUSH_FOLLOW_TAGS;
+               else
+                       *flags &= ~TRANSPORT_PUSH_FOLLOW_TAGS;
+               return 0;
+       }
+
+       return git_default_config(k, v, NULL);
+}
+
 int cmd_push(int argc, const char **argv, const char *prefix)
 {
        int flags = 0;
@@ -493,7 +512,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                  0, CAS_OPT_NAME, &cas, N_("refname>:<expect"),
                  N_("require old value of ref to be at this value"),
                  PARSE_OPT_OPTARG, parseopt_push_cas_option },
-               { OPTION_CALLBACK, 0, "recurse-submodules", &flags, N_("check"),
+               { OPTION_CALLBACK, 0, "recurse-submodules", &flags, "check|on-demand",
                        N_("control recursive pushing of submodules"),
                        PARSE_OPT_OPTARG, option_parse_recurse_submodules },
                OPT_BOOL( 0 , "thin", &thin, N_("use thin pack")),
@@ -507,11 +526,13 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                OPT_BIT(0, "no-verify", &flags, N_("bypass pre-push hook"), TRANSPORT_PUSH_NO_HOOK),
                OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"),
                        TRANSPORT_PUSH_FOLLOW_TAGS),
+               OPT_BIT(0, "signed", &flags, N_("GPG sign the push"), TRANSPORT_PUSH_CERT),
+               OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
                OPT_END()
        };
 
        packet_trace_identity("push");
-       git_config(git_default_config, NULL);
+       git_config(git_push_config, &flags);
        argc = parse_options(argc, argv, prefix, options, push_usage, 0);
 
        if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR))))