Jesse Leite
Jesse Leite

Reputation: 7991

Error "Fatal: Not possible to fast-forward, aborting"

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

Answers (22)

amit anand
amit anand

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

auvipy
auvipy

Reputation: 1188

git pull origin --no-ff fixed the problem for me.

Upvotes: 36

jthomas
jthomas

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

Md Wahiduzzaman Emon
Md Wahiduzzaman Emon

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

** Recommended

Also -you can try this command

git pull --no-ff

Response in the terminal-

  1. Please enter a commit message to explain why this merge is necessary.
  2. especially if it merges an updated upstream into a topic branch.
  3. Lines starting with '#' will be ignored, and an empty message aborts the commit.

After that normally git add, commit and push

Upvotes: 101

Akshay patel
Akshay patel

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:

  1. [pull] ff = no

    If step 1 is not working for you then apply step 2.

  2. git pull --ff-only or git config --global pull.ff only

Upvotes: -2

Ajmal Hasan
Ajmal Hasan

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

LeGEC
LeGEC

Reputation: 51790

When will I see this message?

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)

How can I see what doesn't work?

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.

What can I do to fix this?

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:

  • cherry-pick some of your commits on top of the remote branch,
  • use git rebase -i,
  • merge the other way around...

How can I avoid this when I run 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

Gabriel GMM
Gabriel GMM

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

Muhammad Moiz Younis
Muhammad Moiz Younis

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:

  1. press i
  2. pressEsc
  3. press :wq

Upvotes: 23

Rahimuddin
Rahimuddin

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

Siddhesh Jungade
Siddhesh Jungade

Reputation: 65

This works for me

git pull --rebase <remote> <branch>

Upvotes: 3

Siddhartha Mukherjee
Siddhartha Mukherjee

Reputation: 2943

It works for me. You can use:

git pull --no-ff

Upvotes: 17

Sadman Ahmed
Sadman Ahmed

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

Ajit Parida
Ajit Parida

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

Aman Bhardwaj
Aman Bhardwaj

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

rilian
rilian

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

Dheeraj kumar Rao
Dheeraj kumar Rao

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

crypdick
crypdick

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

Fes Nguyen
Fes Nguyen

Reputation: 638

If you have a commit, try undo it and pull again!

Upvotes: -6

SushiGuy
SushiGuy

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

Pratik Soni
Pratik Soni

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

Amber
Amber

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

Related Questions