'git push' failing because of non-fast forward is a very common situation, and a beginner does not necessarily understand "fast forward" immediately. Signed-off-by: Matthieu Moy <Matthieu.Moy@xxxxxxx> --- (hmm, I thought I had sent this v2 already, but seems I didn't) With grammar fixes from Michael J Gruber. Junio, this comes on top of your patch, since it refers to the to-be-added section in 'git push --help'. builtin-push.c | 10 +++++++++- transport.c | 10 +++++++--- transport.h | 3 ++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/builtin-push.c b/builtin-push.c index 1d92e22..5d4df7f 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -140,6 +140,7 @@ static int do_push(const char *repo, int flags) struct transport *transport = transport_get(remote, url[i]); int err; + int nonfastforward; if (receivepack) transport_set_option(transport, TRANS_OPT_RECEIVEPACK, receivepack); @@ -148,13 +149,20 @@ static int do_push(const char *repo, int flags) if (flags & TRANSPORT_PUSH_VERBOSE) fprintf(stderr, "Pushing to %s\n", url[i]); - err = transport_push(transport, refspec_nr, refspec, flags); + err = transport_push(transport, refspec_nr, refspec, flags, + &nonfastforward); err |= transport_disconnect(transport); if (!err) continue; error("failed to push some refs to '%s'", url[i]); + if (nonfastforward) { + printf("Push was rejected because it would not result in a fast forward:\n" + "Merge in the remote changes (using git pull) before pushing yours,\n" + "or use git push --force to discard the remote changes.\n" + "See 'non-fast forward' section of 'git push --help' for details.\n"); + } errs++; } return !!errs; diff --git a/transport.c b/transport.c index de0d587..f231b35 100644 --- a/transport.c +++ b/transport.c @@ -820,7 +820,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i } static void print_push_status(const char *dest, struct ref *refs, - int verbose, int porcelain) + int verbose, int porcelain, int * nonfastforward) { struct ref *ref; int n = 0; @@ -835,11 +835,14 @@ static void print_push_status(const char *dest, struct ref *refs, if (ref->status == REF_STATUS_OK) n += print_one_push_status(ref, dest, n, porcelain); + *nonfastforward = 0; for (ref = refs; ref; ref = ref->next) { if (ref->status != REF_STATUS_NONE && ref->status != REF_STATUS_UPTODATE && ref->status != REF_STATUS_OK) n += print_one_push_status(ref, dest, n, porcelain); + if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD) + *nonfastforward = 1; } } @@ -997,7 +1000,8 @@ int transport_set_option(struct transport *transport, } int transport_push(struct transport *transport, - int refspec_nr, const char **refspec, int flags) + int refspec_nr, const char **refspec, int flags, + int * nonfastforward) { verify_remote_names(refspec_nr, refspec); @@ -1024,7 +1028,7 @@ int transport_push(struct transport *transport, ret = transport->push_refs(transport, remote_refs, flags); - print_push_status(transport->url, remote_refs, verbose | porcelain, porcelain); + print_push_status(transport->url, remote_refs, verbose | porcelain, porcelain, nonfastforward); if (!(flags & TRANSPORT_PUSH_DRY_RUN)) { struct ref *ref; diff --git a/transport.h b/transport.h index 51b5397..639f13d 100644 --- a/transport.h +++ b/transport.h @@ -68,7 +68,8 @@ int transport_set_option(struct transport *transport, const char *name, const char *value); int transport_push(struct transport *connection, - int refspec_nr, const char **refspec, int flags); + int refspec_nr, const char **refspec, int flags, + int * nonfastforward); const struct ref *transport_get_remote_refs(struct transport *transport); -- 1.6.4.62.g39c83.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html