To prepare our uses for the upcoming changes we should warn them and let
them know that they will need to specify a merge or a rebase in the
future (when a non-fast-forward situation arises). Also, let them know
we fallback to 'git pull --merge', so when the obsoletion of this mode
comes, they know what to type without interrupting or changing their

Signed-off-by: Felipe Contreras <>
 Documentation/git-pull.txt | 18 ++++++++++++++++++                | 15 ++++++++++++---
 t/            | 14 ++++++++++++++
 3 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt
index 767bca3..fe3d15d 100644
--- a/Documentation/git-pull.txt
+++ b/Documentation/git-pull.txt
@@ -23,6 +23,7 @@ More precisely, 'git pull' runs 'git fetch' with the given
 parameters and calls 'git merge' to merge the retrieved branch
 heads into the current branch.
 With `--rebase`, it runs 'git rebase' instead of 'git merge'.
+With `--merge`, it forces the merge, even if it's non-fast forward.
 <repository> should be the name of a remote repository as
 passed to linkgit:git-fetch[1].  <refspec> can name an
@@ -41,11 +42,28 @@ Assume the following history exists and the current branch 
          A---B---C master on origin
+    D---E master
+Then `git pull` will merge in a fast-foward way up to the new master.
+    D---E---A---B---C master, origin/master
+However, a non-fast-foward case looks very different.
+         A---B---C master on origin
+        /
     D---E---F---G master
        origin/master in your repository
+By default `git pull` will warn about these situations, however, most likely
+you would want to force a merge, which you can do with `git pull --merge`.
 Then "`git pull`" will fetch and replay the changes from the remote
 `master` branch since it diverged from the local `master` (i.e., `E`)
 until its current commit (`C`) on top of `master` and record the
diff --git a/ b/
index 2446417..c4a0b08 100755
--- a/
+++ b/
@@ -78,7 +78,7 @@ then
                rebase=$(bool_or_string_config pull.rebase)
-test -z "$mode" && mode=merge
+test -z "$mode" && mode=default
 while :
@@ -317,13 +317,22 @@ case "$merge_head" in
        # check if a non-fast-foward merge would be needed
        merge_head=${merge_head% }
-       if test "$mode" = 'ff-only' && test -z 
"$no_ff$ff_only${squash#--no-squash}" &&
+       if test -z "$no_ff$ff_only${squash#--no-squash}" &&
                test -n "$orig_head" &&
                ! git merge-base --is-ancestor "$orig_head" "$merge_head" &&
                ! git merge-base --is-ancestor "$merge_head" "$orig_head"
-               die "$(gettext "The pull was not fast-forward, please either 
merge or rebase.
+               case "$mode" in
+               ff-only)
+                       die "$(gettext "The pull was not fast-forward, please 
either merge or rebase.
 If unsure, run 'git pull --merge'.")"
+                       ;;
+               default)
+                       warn "$(gettext "the pull was not fast-forward, in the 
future you would have to choose
+a merge or a rebase, falling back to old style for now (git pull --merge).
+Read 'git pull --help' for more information.")" >&2
+                       ;;
+               esac
diff --git a/t/ b/t/
index a548c1b..c96834e 100755
--- a/t/
+++ b/t/
@@ -401,4 +401,18 @@ test_expect_success 'git pull non-fast-forward with merge 
(ff-only)' '
        git pull --merge
+test_expect_success 'git pull non-fast-forward (default)' '
+       test_when_finished "git checkout master && git branch -D other test" &&
+       git checkout -b other master^ &&
+       >new &&
+       git add new &&
+       git commit -m new &&
+       git checkout -b test -t other &&
+       git reset --hard master &&
+       git pull 2> error &&
+       cat error &&
+       grep -q "the pull was not fast-forward" error &&
+       grep -q "in the future you would have to choose" error

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to
More majordomo info at

Reply via email to