path: root/builtin/push.c
diff options
authorJunio C Hamano <>2012-05-02 20:51:24 (GMT)
committerJunio C Hamano <>2012-05-02 20:51:24 (GMT)
commita3db8511b79c1a169c70caf07cedf21358101c60 (patch)
tree30833024bfe2acb6f13ca75c557ade5f567fcaac /builtin/push.c
parentd4a5d872c05057c415347896bd416006153e4b03 (diff)
parentf4d80d2639f8ef55c99c3b035c0312969acc7f01 (diff)
Merge branch 'mm/simple-push'
New users tend to work on one branch at a time and push the result out. The current and upstream modes of push is a more suitable default mode than matching mode for these people, but neither is surprise-free depending on how the project is set up. Introduce a "simple" mode that is a subset of "upstream" but only works when the branch is named the same between the remote and local repositories. The plan is to make it the new default when push.default is not configured. By Matthieu Moy (5) and others * mm/simple-push: push.default doc: explain simple after upstream push: document the future default change for push.default (matching -> simple) t5570: use explicit push refspec push: introduce new push.default mode "simple" add helper functions Undocument deprecated alias 'push.default=tracking' Documentation: explain push.default option a bit more
Diffstat (limited to 'builtin/push.c')
1 files changed, 45 insertions, 2 deletions
diff --git a/builtin/push.c b/builtin/push.c
index 19c40d7..fdfcc6c 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -76,7 +76,44 @@ static int push_url_of_remote(struct remote *remote, const char ***url_p)
return remote->url_nr;
-static void setup_push_upstream(struct remote *remote)
+static NORETURN int die_push_simple(struct branch *branch, struct remote *remote) {
+ /*
+ * There's no point in using shorten_unambiguous_ref here,
+ * as the ambiguity would be on the remote side, not what
+ * we have locally. Plus, this is supposed to be the simple
+ * mode. If the user is doing something crazy like setting
+ * upstream to a non-branch, we should probably be showing
+ * them the big ugly fully qualified ref.
+ */
+ const char *advice_maybe = "";
+ const char *short_upstream =
+ skip_prefix(branch->merge[0]->src, "refs/heads/");
+ if (!short_upstream)
+ short_upstream = branch->merge[0]->src;
+ /*
+ * Don't show advice for people who explicitely set
+ * push.default.
+ */
+ if (push_default == PUSH_DEFAULT_UNSPECIFIED)
+ advice_maybe = _("\n"
+ "To choose either option permanently, "
+ "see push.default in 'git help config'.");
+ die(_("The upstream branch of your current branch does not match\n"
+ "the name of your current branch. To push to the upstream branch\n"
+ "on the remote, use\n"
+ "\n"
+ " git push %s HEAD:%s\n"
+ "\n"
+ "To push to the branch of the same name on the remote, use\n"
+ "\n"
+ " git push %s %s\n"
+ "%s"),
+ remote->name, short_upstream,
+ remote->name, branch->name, advice_maybe);
+static void setup_push_upstream(struct remote *remote, int simple)
struct strbuf refspec = STRBUF_INIT;
struct branch *branch = branch_get(NULL);
@@ -103,6 +140,8 @@ static void setup_push_upstream(struct remote *remote)
"your current branch '%s', without telling me what to push\n"
"to update which remote branch."),
remote->name, branch->name);
+ if (simple && strcmp(branch->refname, branch->merge[0]->src))
+ die_push_simple(branch, remote);
strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
@@ -119,8 +158,12 @@ static void setup_default_push_refspecs(struct remote *remote)
+ setup_push_upstream(remote, 1);
+ break;
- setup_push_upstream(remote);
+ setup_push_upstream(remote, 0);