TechEarl

Git: 'Need to Specify How to Reconcile Divergent Branches' - How to Fix It

Git refuses to pull because your local and remote branches both have new commits. Pick how to combine them: merge or rebase. Here is the one-line fix and what each choice does.

Ishan Karunaratne⏱️ 7 min readUpdated
Share thisCopied
How to fix the Git error 'Need to specify how to reconcile divergent branches' by setting pull.rebase to merge or rebase.

Git stopped your git pull because your local branch and the remote branch have both gained new commits since they last matched, and Git will not guess whether to combine them with a merge or a rebase. Tell it which you want. The fastest one-line fix is to default to merge:

bash
git config --global pull.rebase false

Then run git pull again. That is it. The rest of this page explains why the message appeared, what the merge-versus-rebase choice actually changes, and how to set it per-pull instead of globally.

What the error looks like

When you run git pull and the two branches have diverged, Git 2.27 and newer prints this and refuses to continue:

text
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.rebase false  # merge
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only        # fast-forward only
fatal: Need to specify how to reconcile divergent branches.

The hint is the fix, written right into the error. You just have to pick one of the three lines.

What "divergent branches" actually means

A git pull is two steps: fetch the remote's commits, then integrate them into your current branch. When your branch has not changed locally, that integration is trivial: Git just fast-forwards your branch pointer to the remote's tip. No new commit, no decision.

The trouble starts when both sides have moved. Say you and a teammate both branched from the same commit. They pushed a commit to origin/main; meanwhile you committed locally to main without pulling first. Now neither branch is an ancestor of the other. They have diverged. Git cannot fast-forward, so it has to genuinely combine two lines of history, and there are two valid ways to do that. That is the decision Git is refusing to make for you. The very same divergence, seen from the other direction, is what produces the non-fast-forward push that blocks you when you try to push instead of pull.

If this is unfamiliar territory, my walkthrough of what branches are and how they move covers the underlying model, and the difference between fetching and pulling explains why a pull is really a fetch plus an integration step.

Why Git started demanding this in 2.27

Before Git 2.27 (released in June 2020), a plain git pull on divergent branches silently created a merge commit. That default was convenient but quietly opinionated: a lot of people ended up with a history full of "Merge branch 'main' of github.com:..." commits they never meant to make.

So Git 2.27 made the behavior explicit. If you have not told Git your preference, it now stops and asks instead of assuming. The error is not a bug or a broken repo. It is Git declining to pick a workflow on your behalf. Once you set the config once, you will not see it again on that machine.

The three options, and which to pick

Each hint line maps to a different way of integrating the remote commits.

SettingWhat git pull doesHistory shapeGood default for
pull.rebase falseMerge: creates a merge commit joining both linesPreserves the real branching, adds merge commitsBeginners, shared branches, "I just want it to work"
pull.rebase trueRebase: replays your local commits on top of the remote'sLinear, no merge commitsPeople who like clean, straight-line history
pull.ff onlyFast-forward only: refuses to integrate if it cannot fast-forwardNever auto-combines; makes you decide each timePeople who want to be forced to choose manually

If you are new to Git, set pull.rebase false. Merge is the safest mental model: your commits stay exactly as you made them, the remote's commits stay as they are, and a single merge commit ties the two together. Nothing gets rewritten.

bash
git config --global pull.rebase false
git pull

If you would rather keep a clean, linear history with no merge commits, choose rebase:

bash
git config --global pull.rebase true
git pull

Rebase takes the commits you made locally, sets them aside, fast-forwards your branch to the remote tip, then re-applies your commits one by one on top. The end result reads as a straight line, but be aware that it rewrites your local commits (they get new commit IDs). That is fine for commits you have not pushed anywhere; it is the reason you should never rebase commits other people have already pulled. I go deeper on the trade-off in merge versus rebase.

The third option, pull.ff only, tells Git to only ever fast-forward. If it cannot (because the branches diverged), it stops and does nothing, leaving you to run git merge or git rebase by hand. It is the most explicit of the three and a reasonable choice once you understand the other two.

Global, per-repo, or per-pull

--global writes the setting to your ~/.gitconfig so every repository on the machine uses it. That is usually what you want; the choice is a personal workflow preference, not something that should differ per project. This config only governs how a pull integrates; if the branch you are on has no remote counterpart at all, you will instead need to set its upstream tracking branch before a bare git pull knows where to pull from.

To set it for just the current repository (drop --global):

bash
git config pull.rebase false

To decide a single pull without saving any config at all, pass the flag directly:

bash
git pull --no-rebase   # merge, just this once
git pull --rebase      # rebase, just this once
git pull --ff-only     # fast-forward only, just this once

A command-line flag always wins over the config, so git pull --rebase rebases even if your config says pull.rebase false.

What if the merge or rebase hits a conflict?

Choosing merge or rebase tells Git how to combine the histories. It does not guarantee the combination is automatic. If your commits and the remote's commits touched the same lines, you will get a conflict to resolve either way. That is normal and separate from this error. When it happens, work through it with my guide to resolving merge conflicts.

If you are part-way through a pull that went wrong and you want to back out, a rebase can be stopped with git rebase --abort and a merge with git merge --abort, which both return you to where you started.

A safer habit: pull before you commit

This error is fundamentally a "you and the remote moved at the same time" situation. You can sidestep it most of the time by pulling before you start committing, so your local branch begins from the current remote tip. When you do have unfinished work in the way, git stash lets you set it aside, pull cleanly, and reapply your changes on top.

For the broader picture of how fetch, merge, and pull fit together as you start out, see the Git for beginners hub, which links the whole series. And if you keep ending up with diverged history on a shared branch, it is worth reading how teams structure their flow in Git workflows for teams.

FAQ

Sources

Authoritative references this article was fact-checked against.

Tagsdivergent branchesGitVersion Controlgit pullgit config

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts