diff options
Diffstat (limited to 'builtin/push.c')
-rw-r--r-- | builtin/push.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/builtin/push.c b/builtin/push.c index 2d84d10720..6d36c24268 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -120,10 +120,11 @@ static const char message_detached_head_die[] = "\n" " git push %s HEAD:<name-of-remote-branch>\n"); -static void setup_push_upstream(struct remote *remote, int simple) +static void setup_push_upstream(struct remote *remote, struct branch *branch, + int triangular) { struct strbuf refspec = STRBUF_INIT; - struct branch *branch = branch_get(NULL); + if (!branch) die(_(message_detached_head_die), remote->name); if (!branch->merge_nr || !branch->merge || !branch->remote_name) @@ -137,18 +138,29 @@ static void setup_push_upstream(struct remote *remote, int simple) if (branch->merge_nr != 1) die(_("The current branch %s has multiple upstream branches, " "refusing to push."), branch->name); - if (strcmp(branch->remote_name, remote->name)) + if (triangular) die(_("You are pushing to remote '%s', which is not the upstream of\n" "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); + + if (push_default == PUSH_DEFAULT_SIMPLE) { + /* Additional safety */ + if (strcmp(branch->refname, branch->merge[0]->src)) + die_push_simple(branch, remote); + } strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src); add_refspec(refspec.buf); } +static void setup_push_current(struct remote *remote, struct branch *branch) +{ + if (!branch) + die(_(message_detached_head_die), remote->name); + add_refspec(branch->name); +} + static char warn_unspecified_push_default_msg[] = N_("push.default is unset; its implicit value is changing in\n" "Git 2.0 from 'matching' to 'simple'. To squelch this message\n" @@ -173,9 +185,16 @@ static void warn_unspecified_push_default_configuration(void) warning("%s\n", _(warn_unspecified_push_default_msg)); } +static int is_workflow_triangular(struct remote *remote) +{ + struct remote *fetch_remote = remote_get(NULL); + return (fetch_remote && fetch_remote != remote); +} + static void setup_default_push_refspecs(struct remote *remote) { - struct branch *branch; + struct branch *branch = branch_get(NULL); + int triangular = is_workflow_triangular(remote); switch (push_default) { default: @@ -188,18 +207,18 @@ static void setup_default_push_refspecs(struct remote *remote) break; case PUSH_DEFAULT_SIMPLE: - setup_push_upstream(remote, 1); + if (triangular) + setup_push_current(remote, branch); + else + setup_push_upstream(remote, branch, triangular); break; case PUSH_DEFAULT_UPSTREAM: - setup_push_upstream(remote, 0); + setup_push_upstream(remote, branch, triangular); break; case PUSH_DEFAULT_CURRENT: - branch = branch_get(NULL); - if (!branch) - die(_(message_detached_head_die), remote->name); - add_refspec(branch->name); + setup_push_current(remote, branch); break; case PUSH_DEFAULT_NOTHING: @@ -211,8 +230,8 @@ static void setup_default_push_refspecs(struct remote *remote) static const char message_advice_pull_before_push[] = N_("Updates were rejected because the tip of your current branch is behind\n" - "its remote counterpart. Merge the remote changes (e.g. 'git pull')\n" - "before pushing again.\n" + "its remote counterpart. Integrate the remote changes (e.g.\n" + "'git pull ...') before pushing again.\n" "See the 'Note about fast-forwards' in 'git push --help' for details."); static const char message_advice_use_upstream[] = @@ -223,15 +242,15 @@ static const char message_advice_use_upstream[] = static const char message_advice_checkout_pull_push[] = N_("Updates were rejected because a pushed branch tip is behind its remote\n" - "counterpart. Check out this branch and merge the remote changes\n" - "(e.g. 'git pull') before pushing again.\n" + "counterpart. Check out this branch and integrate the remote changes\n" + "(e.g. 'git pull ...') before pushing again.\n" "See the 'Note about fast-forwards' in 'git push --help' for details."); static const char message_advice_ref_fetch_first[] = N_("Updates were rejected because the remote contains work that you do\n" "not have locally. This is usually caused by another repository pushing\n" - "to the same ref. You may want to first merge the remote changes (e.g.,\n" - "'git pull') before pushing again.\n" + "to the same ref. You may want to first integrate the remote changes\n" + "(e.g., 'git pull ...') before pushing again.\n" "See the 'Note about fast-forwards' in 'git push --help' for details."); static const char message_advice_ref_already_exists[] = |