Skip to content

When git pull doesn't work due to divergent upstream history

Ildar Sagdejev edited this page Jun 12, 2022 · 1 revision

Sometimes git pull results in a message like:

  • You have divergent branches and need to specify how to reconcile them
  • Not possible to fast-forward, aborting

This happens when your local branch history is not completely contained inside the remote branch history (in other words, the branches are divergent), and may occur in one of several scenarios.

Scenario: You have made local commits while new commits were pushed upstream

In this case run:

$ git pull --rebase

This will intelligently reapply your changes (taking into account the previous state of the remote branch, if locally available) on top of the remote changes. Merge conflicts may arise.

Scenario: Someone has force pushed to the upstream repository

Even though it is strongly not recommended to force push an alternative history to a remote branch that other people may be already basing their work on, developers might nevertheless sometimes exhibit pure alpha behavior and alter the commit history on a branch that you are attempting to pull from.

If this is the case, you will see something like:

$ git pull
remote: Enumerating objects: 4, done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 4
Unpacking objects: 100% (4/4), 13.30 KiB | 1.66 MiB/s, done.
From github.com:earthstewards/littermap
   c9cad0a..adfa5e9  master        -> origin/master
fatal: Not possible to fast-forward, aborting.

In this case, if you don't care about any of your local changes, you can just:

$ git reset --hard origin/master

Replace origin/master with the exact remote branch you need, if it is different.

If you want to keep your local uncommitted changes, but don't have any significant commits that were rewritten in the remote history:

$ git stash
$ git reset --hard origin/master
$ git stash pop

If you do have local commits that are rewritten or missing in the remote repository, the complexity of the situation must be faced directly:

$ git pull --rebase

And then do whatever you need to do.