Permalink
Browse files

Merge branch 'rr/triangle' into next

Support "pull from one place, push to another place" workflow
better by introducing remote.pushdefault (overrides the "origin"
thing) and branch.*.pushremote (overrides the branch.*.remote).

* rr/triangle:
  remote.c: introduce branch.<name>.pushremote
  remote.c: introduce remote.pushdefault
  remote.c: introduce a way to have different remotes for fetch/push
  t5516 (fetch-push): drop implicit arguments from helper functions
  t5516 (fetch-push): update test description
  remote.c: simplify a bit of code using git_config_string()

# Conflicts:
# 	t/t5516-fetch-push.sh
  • Loading branch information...
2 parents b7632e0 + 9f765ce commit 2d2c8eea4ebcf41b172cb33cdfbacec4492275c8 @gitster gitster committed Apr 4, 2013
Showing with 241 additions and 149 deletions.
  1. +21 −3 Documentation/config.txt
  2. +1 −1 builtin/push.c
  3. +34 −7 remote.c
  4. +1 −0 remote.h
  5. +184 −138 t/t5516-fetch-push.sh
View
@@ -727,9 +727,22 @@ branch.autosetuprebase::
This option defaults to never.
branch.<name>.remote::
- When in branch <name>, it tells 'git fetch' and 'git push' which
- remote to fetch from/push to. It defaults to `origin` if no remote is
- configured. `origin` is also used if you are not on any branch.
+ When on branch <name>, it tells 'git fetch' and 'git push'
+ which remote to fetch from/push to. The remote to push to
+ may be overridden with `remote.pushdefault` (for all branches).
+ The remote to push to, for the current branch, may be further
+ overridden by `branch.<name>.pushremote`. If no remote is
+ configured, or if you are not on any branch, it defaults to
+ `origin` for fetching and `remote.pushdefault` for pushing.
+
+branch.<name>.pushremote::
+ When on branch <name>, it overrides `branch.<name>.remote` for
+ pushing. It also overrides `remote.pushdefault` for pushing
+ from branch <name>. When you pull from one place (e.g. your
+ upstream) and push to another place (e.g. your own publishing
+ repository), you would want to set `remote.pushdefault` to
+ specify the remote to push to for all branches, and use this
+ option to override it for a specific branch.
branch.<name>.merge::
Defines, together with branch.<name>.remote, the upstream branch
@@ -1898,6 +1911,11 @@ 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
+ `branch.<name>.remote` for all branches, and is overridden by
+ `branch.<name>.pushremote` for specific branches.
+
remote.<name>.url::
The URL of a remote repository. See linkgit:git-fetch[1] or
linkgit:git-push[1].
View
@@ -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;
View
@@ -49,6 +49,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;
@@ -357,13 +358,16 @@ static int handle_config(const char *key, const char *value, void *cb)
return 0;
branch = make_branch(name, subkey - name);
if (!strcmp(subkey, ".remote")) {
- if (!value)
- return config_error_nonbool(key);
- branch->remote_name = xstrdup(value);
+ if (git_config_string(&branch->remote_name, key, value))
+ return -1;
if (branch == current_branch) {
default_remote_name = branch->remote_name;
explicit_default_remote_name = 1;
}
+ } else if (!strcmp(subkey, ".pushremote")) {
+ if (branch == current_branch)
+ if (git_config_string(&pushremote_name, key, value))
+ return -1;
} else if (!strcmp(subkey, ".merge")) {
if (!value)
return config_error_nonbool(key);
@@ -389,9 +393,16 @@ 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;
+
+ /* Handle remote.* variables */
+ if (!strcmp(name, "pushdefault"))
+ return git_config_string(&pushremote_name, key, value);
+
+ /* Handle remote.<name>.* variables */
if (*name == '/') {
warning("Config remote shorthand cannot begin with '/': %s",
name);
@@ -671,17 +682,21 @@ static int valid_remote_nick(const char *name)
return !strchr(name, '/'); /* no slash */
}
-struct remote *remote_get(const char *name)
+static struct remote *remote_get_1(const char *name, const char *pushremote_name)
{
struct remote *ret;
int name_given = 0;
- read_config();
if (name)
name_given = 1;
else {
- name = default_remote_name;
- name_given = explicit_default_remote_name;
+ 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);
@@ -700,6 +715,18 @@ struct remote *remote_get(const char *name)
return ret;
}
+struct remote *remote_get(const char *name)
+{
+ read_config();
+ return remote_get_1(name, NULL);
+}
+
+struct remote *pushremote_get(const char *name)
+{
+ read_config();
+ return remote_get_1(name, pushremote_name);
+}
+
int remote_is_configured(const char *name)
{
int i;
View
@@ -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);
Oops, something went wrong.

0 comments on commit 2d2c8ee

Please sign in to comment.