Skip to main content
DevOps Insightsguides & answers

Git · troubleshooting

fatal: Need to specify how to reconcile divergent branches

Your branch and the remote both have commits the other lacks, and since Git 2.33.1 git pull will not choose between merging and rebasing for you. Pick one for this pull with --rebase or --no-rebase, or set pull.rebase once.

Reproduced on Git 2.50.1, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 9 sections

Before you start

  • A terminal in the repository, with any uncommitted work committed or stashed.

Run this first

step 1 of 2
git fetch && git log --oneline --graph --left-right HEAD...@{u}

Look for Commits on both sides

Shows the commits only you have (<) and only the remote has (>).

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Which message did git pull end with?

Cause space

2 of 2 still possible

  • You and the remote both have new commitsCommon
  • pull.ff only is set, and you have local commitsOccasional

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    git fetch && git log --oneline --graph --left-right HEAD...@{u}

    Shows the commits only you have (<) and only the remote has (>).

    Look for Commits on both sides

  2. Step 2

    git config --show-origin --get-regexp '^pull\.'

    Shows any pull preference and where it is set.

    Look for No pull.rebase or pull.ff, or pull.ff only

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

You and the remote both have new commits

Common

Someone pushed to the branch while you committed locally, and no pull preference is configured, so Git will not pick a strategy.

Confirm

git fetch && git status -sb

ahead N, behind M at the same time

Fix

  • For this pull only: git pull --rebase to put your commits on top (good for unpushed local work), or git pull --no-rebase to merge.
  • Set your preference once: git config --global pull.rebase true (rebase) or false (merge), or pull.ff only if you never want Git to combine histories implicitly.
  • Resolve any conflicts the merge or rebase reports, then push.
git pull --rebase

Replays your local commits on top of the remote. Use git pull --no-rebase to merge instead.

pull.ff only is set, and you have local commits

Occasional

With pull.ff=only (often set to avoid accidental merges), any pull that needs a merge or rebase stops with Not possible to fast-forward.

Confirm

git config --show-origin --get pull.ff

only, and the file it is set in (global or this repository)

Fix

  • Integrate deliberately for this branch: git pull --rebase or git pull --no-rebase.
  • Or, if the local commits were a mistake, move them to a new branch first (git branch keep-my-work) and then reset to the remote.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

You committed on your machine, and someone else pushed to the same branch. Now the two histories have split. Git can join them two ways: a merge commit that ties both together, or a rebase that replays your commits on top of theirs. Older Git quietly merged; current Git stops and asks you to choose, once or as a setting.

Words used on this page

Divergent branches
Your branch and its upstream each have commits the other does not: ahead and behind at the same time.
Merge
Joins both lines with a merge commit. History keeps exactly what happened.
Rebase
Replays your local commits on top of the remote ones, giving a straight line. It rewrites your local commits, so do it only to commits you have not shared.
Fast-forward only
Accept the remote only if your branch has no new commits of its own; otherwise stop.
What is actually happening

Reproduced on Git 2.50.1: with commits on both sides and no pull setting, git pull fetched, printed hint: You have divergent branches and need to specify how to reconcile them, listed git config pull.rebase false (merge), pull.rebase true (rebase) and pull.ff only, and exited 128 with fatal: Need to specify how to reconcile divergent branches.

Git 2.27.0 started warning when no pull.rebase was set; the fatal error is in Git's source from v2.33.1. Before that a plain pull merged.

With pull.ff only, the same pull exits 128 with fatal: Not possible to fast-forward, aborting, which is the setting doing its job: it refuses any pull that would need a merge or rebase.

git status shows the state as ahead 1, behind 1 (or similar). Choosing merge or rebase for one pull, or setting it once, both resolve it.

How to tell this is your problem
WhereWhat you see
git pullhint: You have divergent branches and need to specify how to reconcile them. … fatal: Need to specify how to reconcile divergent branches.
git status -sb## main...origin/main [ahead 1, behind 1]
With pull.ff onlyfatal: Not possible to fast-forward, aborting.

How to know it is actually fixed

  • git status -sb shows only ahead N (your commits on top), or up to date after you push.
  • git push succeeds without --force.

Stopping it happening again

  • Set pull.rebase once, globally, to the strategy your team uses.
  • Pull before you start work and before you push, so divergences stay small.

Security considerations

  • Do not reach for git push --force to make the error go away: on a shared branch it deletes the commits others pushed. Integrate them with merge or rebase first.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it