Reputation: 7991
Why is Git not allowing me to fast forward merge anymore?
If I try to force it using --ff-only
, I get the message
fatal: Not possible to fast-forward, aborting.
I realize that there are huge advantages to merge --no-ff
, but I'm just puzzled why I can't --ff-only
now?
Upvotes: 762
Views: 1556224
Reputation: 21
git pull origin --rebase
OR
git merge <branch_name>
The error means that Git is unable to merge the different branches when taking a pull. Instead of taking a pull, perform a merge. Merging and pulling are similar for combining branches, so use merge instead of pull.
Upvotes: -1
Reputation: 2583
Another option (the one I just used) is to fetch the remote branch and then merge it. I find this often solves the problem when a pull won't work.
$ git fetch <remote> <branch>
$ git merge <remote>/<branch>
I'm surprised the fetch and merge solution was not posted here. If there is a good reason this is not a good approach, perhaps someone will let me know.
Upvotes: 5
Reputation: 1213
Try this. It will work nicely.
git pull origin --rebase
After you get the non-fast-forward error, just do below :
git pull --rebase origin <name-of-the-remote-branch>
This will fetch the remote changes to your local branch. On top of that, it will apply your local commits.
Then
git push origin <name-of-the-remote-branch>
This will apply your local changes in the local copy of the remote branch to the actual remote branch repo in git
Also -you can try this command
git pull --no-ff
Response in the terminal-
After that normally git add, commit and push
Upvotes: 101
Reputation: 5
If you get this Git error in the future, this solution will help you
An error while take a pull from (development/master/main) to your local branch:
Error message:
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --re base, --no-re base,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.
Solution:
open your .git configuration file and add these lines:
[pull] ff = no
If step 1 is not working for you then apply step 2.
git pull --ff-only or git config --global pull.ff only
Upvotes: -2
Reputation: 1569
For me this worked. Change branch_name to the actual name of the branch:
git pull origin branch_name --no-ff
Upvotes: 40
Reputation: 51790
When you run git merge --ff-only <some/branch>
or git pull --ff-only <remote> <some/branch>
, and the branch or commit you are trying to merge is not based off your current branch—its history has somehow forked from yours.
git pull
can have defaults set in the configuration, so you can also see this if you ran a plain git pull origin <some/branch>
, and your config has pull.ff = only
.
To check your config: run git config pull.ff
or git config --show-origin pull.ff
(git merge
has a similar merge.ff
option)
To view the history of both your branch and the target branch, you can use:
git log --graph --oneline HEAD <some/branch>
If you didn't explicitly type a branch name (e.g: git merge --ff-only
or git pull --ff-only
), git
defaults to "the upstream branch of your active branch" -- it often is origin/mybranch
. A way to reference that branch from the command line is @{u}
:
git log --graph --oneline HEAD @{u}
# For Powershell users: @{...} is an operator, you will need to quote "@{u}"
git log --graph --oneline HEAD "@{u}"
You should see the divergence between your current branch and the target branch.
See also "More git log
options" below.
This depends on the result you want to reach, and what you see in the history above.
You may want to rebase your commits on top of target commit:
git rebase <some/branch>
# To rebase on top of your default upstream:
git rebase # The same as 'git rebase @{u}'
You may want to run an actual merge instead of only allowing fast forwards:
git merge <some/branch>
git merge # The same as 'git merge @{u}'
Or anything that suits your needs:
git rebase -i
,git pull
?If you have set --ff-only
as a default (e.g: if git config pull.ff
returns only
), you can override this default on a one off basis by explicitly providing a command line flag:
git pull --rebase # Rebase on top of fetched branch, rather than merge it.
git pull --ff # Run a normal merge
# (note: you *will* have a merge commit in your history)
If you want to change that default to some other value:
# Remove that default value, allow normal merges when pulling
git config --global --unset pull.ff
# Run `git pull --rebase` by default
# Note: you still need to run 'git config --global --unset pull.ff'
git config --global pull.rebase true
More git log
options
To see the differences between two branches in your terminal:
git log --oneline --graph a b
will show you the complete histories of a
and b
combined together.
If you want to see the history of a
and b
since they forked:
git log --oneline --graph --boundary a...b
# a...b (3 dots) : Means 'symmetric difference' in git log
# --boundary : Will show the commit that was at the fork point
# without this option, the two histories will be
# printed one below the other
If you want to hide side branches -- for example, if you want to view git log my/branch...master
, but you don't want to view the details of all pull requests that got merged in master
:
git log --oneline --graph --boundary --first-parent a...b
# --first-parent : On merge commits, only follow the first parent
Many graphical frontend to Git (Git Extensions, TortoiseGit, gitk, etc.) have ways to activate these options when you view your repositories history.
Look for the checkboxes in your GUI, and for fields where you may type a...b
or HEAD...@{u}
.
If you intend to use some of these commands on a regular basis, set an alias for them:
# Example: show HEAD vs @{upstream} log
git config --global alias.whatsup 'log --oneline --graph --boundary HEAD...@{u}'
# You can now run:
git whatsup
Upvotes: 5
Reputation: 11
The reason I get this error is that instead of just doing a git checkout
, I was doing git checkout -b
, creating a branch.
Try redoing the process by simply checking out the remote branch.
Upvotes: 1
Reputation: 231
This works for me
git pull --no-ff
Then if you face this thing,
Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
then follow these steps:
i
Esc
:wq
Upvotes: 23
Reputation: 614
Use:
git pull origin main --rebase
git pull --rebase
The above two commands worked for me. But the only problem is I see the commits from the main branch in the current branch too...
Upvotes: 12
Reputation: 161
I was facing the same type of issue, and I guess many of us will be facing this when we are pair programming and we also have incoming commits in the branch from other users. These are the steps I faced, and I solved them by git pull --no-rebase
:
➜ graphql-tutorial git:(filtering) git config pull.ff only
➜ graphql-tutorial git:(filtering) git pull
fatal: Not possible to fast-forward, aborting.
➜ graphql-tutorial git:(filtering) git merge
➜ graphql-tutorial git:(filtering) git config pull.rebase false
➜ graphql-tutorial git:(filtering) git pull
fatal: Not possible to fast-forward, aborting.
➜ graphql-tutorial git:(filtering) git pull --no-rebase
Merge made by the 'ort' strategy.
. <file name>
. <file name>
. <file name>
. <file name>
5 files changed, 47 insertions(+), 9 deletions(-)
create mode 100644 app/models/auth_token.rb
Upvotes: 2
Reputation: 221
You can try this in the terminal, which actually edits your <.gitconfig> file and set ff = no
git config pull.ff no
Upvotes: 20
Reputation: 1689
If
git pull
does not do the trick and if you want to merge both the current changes and the changes that'd come from the pull of the branch from origin then do this:
git merge origin/BRANCH_NAME
After that, resolve the merge conflicts if any and be done for the day.
Upvotes: 127
Reputation: 186
If origin branch was squashed or there was a change that broke commit history, and if you do not care about your local branch commit history, you can just reset your local branch
git checkout branchname
git reset --hard origin/branchname
Upvotes: 4
Reputation: 10202
Use the option --no-ff
to turn off fast-forwarding for one pull:
git pull --no-ff
https://git-scm.com/docs/git-pull#Documentation/git-pull.txt---no-ff
Upvotes: 600
Reputation: 19796
Disclaimer: these commands will bring changes from the remote branch into yours.
git pull --rebase
. Unlike the other solution, you don't need to know the name of your destination branch.
If your upstream branch is not set, try git pull origin <branch> --rebase
(credit to @Rick in the comments)
To set this option globally, use git config --global pull.rebase true
(credit to @Artur Mustafin below)
Upvotes: 1189
Reputation: 1627
If you get this when doing a git pull origin master
on your local branch, open .gitconfig
in Notepad (usually hidden in C:\Users\Myname) and add these two lines
[pull]
ff = no
Save the config and try git pull origin master
again
Upvotes: 34
Reputation: 2588
This is because you have enabled the fast-forward only option. The thing here is your pull from the branch will create a merge commit in your local git and the fast-forward only option doesn't allow creating a merge commit at the time of pull.
In the case of a big team, You will end up rebasing and resolving conflicts lots of the time and for each and every commit coming from the pull.
I suggest you remove ff = only line from git local config file.
$ cd to-my-project-root-dir
$ nano .git/config
[pull]
ff = only // remove this line
rebase = false
Upvotes: 61
Reputation: 526543
Your branch is no longer directly based off of the branch you're trying to merge it into - e.g. another commit was added to the destination branch that isn't in your branch. Thus, you can't fast-forward into it (because fast-forward requires your branch to completely contain the destination branch).
You can rebase your branch on top of the destination branch (git rebase <destination branch>
) to rework the commits such that they will fast forward into it, or you can do a regular merge.
Upvotes: 249