path: root/builtin/push.c
diff options
authorJunio C Hamano <>2013-02-04 18:25:04 (GMT)
committerJunio C Hamano <>2013-02-04 18:25:04 (GMT)
commit370855e967e21d9c5b70df7b5cd3756c7bed5c7c (patch)
tree80d1f70f82ec587ca4919d2289d6087d4979009c /builtin/push.c
parent099ba556d05571001293c8eda10a4fc659f83f48 (diff)
parentb4cf8db27502f613fcff3fd871c8e31d23f49c7d (diff)
Merge branch 'jc/push-reject-reasons'
Improve error and advice messages given locally when "git push" refuses when it cannot compute fast-forwardness by separating these cases from the normal "not a fast-forward; merge first and push again" case. * jc/push-reject-reasons: push: finishing touches to explain REJECT_ALREADY_EXISTS better push: introduce REJECT_FETCH_FIRST and REJECT_NEEDS_FORCE push: further simplify the logic to assign rejection reason push: further clean up fields of "struct ref"
Diffstat (limited to 'builtin/push.c')
1 files changed, 31 insertions, 2 deletions
diff --git a/builtin/push.c b/builtin/push.c
index b158028..42b129d 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -220,9 +220,20 @@ static const char message_advice_checkout_pull_push[] =
"(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"
+ "See the 'Note about fast-forwards' in 'git push --help' for details.");
static const char message_advice_ref_already_exists[] =
- N_("Updates were rejected because the destination reference already exists\n"
- "in the remote.");
+ N_("Updates were rejected because the tag already exists in the remote.");
+static const char message_advice_ref_needs_force[] =
+ N_("You cannot update a remote ref that points at a non-commit object,\n"
+ "or update a remote ref to make it point at a non-commit object,\n"
+ "without using the '--force' option.\n");
static void advise_pull_before_push(void)
@@ -252,6 +263,20 @@ static void advise_ref_already_exists(void)
+static void advise_ref_fetch_first(void)
+ if (!advice_push_fetch_first || !advice_push_update_rejected)
+ return;
+ advise(_(message_advice_ref_fetch_first));
+static void advise_ref_needs_force(void)
+ if (!advice_push_needs_force || !advice_push_update_rejected)
+ return;
+ advise(_(message_advice_ref_needs_force));
static int push_with_options(struct transport *transport, int flags)
int err;
@@ -285,6 +310,10 @@ static int push_with_options(struct transport *transport, int flags)
} else if (reject_reasons & REJECT_ALREADY_EXISTS) {
+ } else if (reject_reasons & REJECT_FETCH_FIRST) {
+ advise_ref_fetch_first();
+ } else if (reject_reasons & REJECT_NEEDS_FORCE) {
+ advise_ref_needs_force();
return 1;