fatal: Need to specify how to reconcile divergent branches. — your branch and the
remote branch each have commits the other does not, and Git will not choose between merging and
rebasing for you. Tell it: git pull --no-rebase merges,
git pull --rebase replays your commits on top of the remote ones.
To stop the question in one repository, run git config pull.rebase false (merge) or
git config pull.rebase true (rebase); add --global to make it the
default everywhere. Nothing is lost when the pull fails: it has already fetched, and your
commits are untouched.
The error
$ git pull
From ../origin
7a9bfe6..eb5a272 main -> origin/main
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
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
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.
$ git status -sb
## main...origin/main [ahead 1, behind 1]
With pull.ff set to only, the same situation ends differently:
$ git config pull.ff only
$ git pull
hint: Diverging branches can't be fast-forwarded, you need to either:
hint:
hint: git merge --no-ff
hint:
hint: or:
hint:
hint: git rebase
hint:
hint: Disable this message with "git config advice.diverging false"
fatal: Not possible to fast-forward, aborting.
Why it happens
A pull is a fetch followed by an integration step. When your branch is only behind, Git
fast-forwards: it moves the branch pointer and nothing needs deciding. Here both sides moved. A
teammate pushed a commit while you made one locally, which is what [ahead 1, behind 1]
means, and two answers are valid: a merge commit that joins the two lines, or a rebase that
replays your commit on top of theirs. Without a pull.rebase or pull.ff
setting, Git refuses to pick. pull.ff only allows the fast-forward case alone, so it
aborts as soon as the branches diverge.
On the test PC a plain git pull did not fail at first:
git config --show-origin pull.rebase printed
file:C:/Program Files/Git/etc/gitconfig with false, so Git for Windows
merged silently. The error appeared once that system file was ignored. Ubuntu 24.04 in WSL on the
same PC (Git 2.43.0) has no system config file at all, so a fresh setup there has no pull setting
either, which is the situation the test reproduced.
The fix
Merge, once:
$ git pull --no-rebase
Merge made by the 'ort' strategy.
r1-david.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 r1-david.txt
$ git log --oneline --graph
* 7d63a5c Merge branch 'main' of ../origin
|\
| * eb5a272 Add r1-david.txt
* | f063169 Add r1-maria.txt
|/
* 7a9bfe6 Add README
Rebase, once:
$ git pull --rebase
Successfully rebased and updated refs/heads/main.
$ git log --oneline --graph -4
* 35a57b7 Add r2-maria.txt
* 798eac9 Add r2-david.txt
Or set it for the repository, after which a plain git pull works:
$ git config pull.rebase true
$ git pull
From ../origin
4adfe28..934ed80 main -> origin/main
Successfully rebased and updated refs/heads/main.
$ git config --show-origin pull.rebase
file:.git/config true
git config pull.rebase false gave the merge in the same way. With
pull.ff only still set, both git pull --rebase and
git pull --no-rebase went through: an option on the command line beats the
setting. Every fix ended with a successful git push. Which to choose: on a feature
branch only you push to, --rebase keeps your commits in a straight line on top of
the latest work; on a shared main, use what the team agreed, and when nobody agreed
anything, the merge is the option that never changes a commit's ID.
How it was reproduced
Git for Windows 2.45.2 (git version 2.45.2.windows.1) in Git Bash 5.2.26. A local
bare repository, origin.git, stood in for the hosted remote, so the output says
../origin where you would see your remote's URL. Two clones with fictional
identities: David committed and pushed one file, Maria committed another locally, then ran
git pull. The personal global config was replaced by an empty file
(GIT_CONFIG_GLOBAL) and the system file was ignored with
GIT_CONFIG_NOSYSTEM=1; a final round with the system file back merged without
asking.
Frequently asked
- What does 'Need to specify how to reconcile divergent branches' mean?
- Your local branch and the remote branch both have commits the other does not. git pull can combine them by merging or by rebasing, and with no pull.rebase or pull.ff setting it refuses to choose for you.
- Should I use git pull --rebase or git pull --no-rebase?
- --no-rebase creates a merge commit and leaves every existing commit as it is. --rebase replays your unpushed commits on top of the remote ones, which gives a straight history and new IDs for your commits. Rebase suits your own feature branch; on main follow the team's rule.
- How do I set the default for git pull once for all repositories?
- Run git config --global pull.rebase false for merge or git config --global pull.rebase true for rebase. Without --global the setting applies to the current repository only. git config --show-origin pull.rebase shows which file the current value comes from.
More decoded errors in the Fixes category. The push side of the same situation, when the remote has commits you have not pulled yet: rejected, fetch first.