This new configuration variable overrides branch-specific
configuration `branch.<name>.remote` for pushes.  It is useful in the
typical scenario, where the remote I'm pulling from is not the remote
I'm pushing to.

Signed-off-by: Ramkumar Ramachandra <artag...@gmail.com>
---
 Junio C Hamano wrote:
 > As the first cut, I would have expected the series to start from
 > more general (not "only this branch"), with later follow-up to let
 > more specific configuration.

 Doesn't that follow trivially from my previous patch?  I'm looking
 for comments on how best to share code between pushremote_get()/
 remote_get(), and on other remote_get() callsites.

 > Also I'd prefer to see the "push" semantics (e.g. "what does
 > upstream mean in this new world order?") designed better first.

 Why should the meaning of upstream change?  We'd probably like to
 introduce something like a branch@{downstream} pointing to the push
 remote ref sometime in the future though.  Wait, should it always be
 called downstream?

 Documentation/config.txt |  4 ++++
 builtin/push.c           |  2 +-
 remote.c                 | 45 +++++++++++++++++++++++++++++++++++++++++++--
 remote.h                 |  1 +
 4 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9b11597..82a4a78 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1884,6 +1884,10 @@ receive.updateserverinfo::
        If set to true, git-receive-pack will run git-update-server-info
        after receiving data from git-push and updating refs.
 
+remote.pushdefault::
+       The remote to push to by default.  Overrides the
+       branch-specific configuration `branch.<name>.remote`.
+
 remote.<name>.url::
        The URL of a remote repository.  See linkgit:git-fetch[1] or
        linkgit:git-push[1].
diff --git a/builtin/push.c b/builtin/push.c
index 42b129d..d447a80 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -322,7 +322,7 @@ static int push_with_options(struct transport *transport, 
int flags)
 static int do_push(const char *repo, int flags)
 {
        int i, errs;
-       struct remote *remote = remote_get(repo);
+       struct remote *remote = pushremote_get(repo);
        const char **url;
        int url_nr;
 
diff --git a/remote.c b/remote.c
index e53a6eb..08bb803 100644
--- a/remote.c
+++ b/remote.c
@@ -48,6 +48,7 @@ static int branches_nr;
 
 static struct branch *current_branch;
 static const char *default_remote_name;
+static const char *pushremote_name;
 static int explicit_default_remote_name;
 
 static struct rewrites rewrites;
@@ -349,6 +350,14 @@ static int handle_config(const char *key, const char 
*value, void *cb)
        const char *subkey;
        struct remote *remote;
        struct branch *branch;
+       if (!prefixcmp(key,  "remote.")) {
+               name = key + 7;
+               if (!strcmp(name, "pushdefault")) {
+                       if (!value)
+                               return config_error_nonbool(key);
+                       pushremote_name = xstrdup(value);
+               }
+       }
        if (!prefixcmp(key, "branch.")) {
                name = key + 7;
                subkey = strrchr(name, '.');
@@ -388,8 +397,6 @@ static int handle_config(const char *key, const char 
*value, void *cb)
                        add_instead_of(rewrite, xstrdup(value));
                }
        }
-       if (prefixcmp(key,  "remote."))
-               return 0;
        name = key + 7;
        if (*name == '/') {
                warning("Config remote shorthand cannot begin with '/': %s",
@@ -700,6 +707,40 @@ struct remote *remote_get(const char *name)
        return ret;
 }
 
+struct remote *pushremote_get(const char *name)
+{
+       struct remote *ret;
+       int name_given = 0;
+
+       read_config();
+       if (name)
+               name_given = 1;
+       else {
+               if (pushremote_name) {
+                       name = pushremote_name;
+                       name_given = 1;
+               } else {
+                       name = default_remote_name;
+                       name_given = explicit_default_remote_name;
+               }
+       }
+
+       ret = make_remote(name, 0);
+       if (valid_remote_nick(name)) {
+               if (!valid_remote(ret))
+                       read_remotes_file(ret);
+               if (!valid_remote(ret))
+                       read_branches_file(ret);
+       }
+       if (name_given && !valid_remote(ret))
+               add_url_alias(ret, name);
+       if (!valid_remote(ret))
+               return NULL;
+       ret->fetch = parse_fetch_refspec(ret->fetch_refspec_nr, 
ret->fetch_refspec);
+       ret->push = parse_push_refspec(ret->push_refspec_nr, ret->push_refspec);
+       return ret;
+}
+
 int remote_is_configured(const char *name)
 {
        int i;
diff --git a/remote.h b/remote.h
index 251d8fd..99a437f 100644
--- a/remote.h
+++ b/remote.h
@@ -51,6 +51,7 @@ struct remote {
 };
 
 struct remote *remote_get(const char *name);
+struct remote *pushremote_get(const char *name);
 int remote_is_configured(const char *name);
 
 typedef int each_remote_fn(struct remote *remote, void *priv);
-- 
1.8.1.3.535.ga923c31.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to