Skip to main content

Section C.5 Git Says I Have Divergent Branches!

I recently experienced this issue for the first time and had to do some searching to figure out how to fix it. I relied on Davide Casiraghi’s question on StackOverflow 66  and adrianvlupu’s question also on StackOverflow 67  to create this guide and you might find these resources more helpful than mine.
This is a preemptive warning of a merge conflict and occurs when you are trying to pull in or push out a commit and another commit gets in the way. Git doesn’t want to create them, so it refuses to push or pull until you fix something. This is not the same error as in Section C.4, although it is closely related. You might get something like this:
> git push
To <repo-you-are-pushing-to>.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to '<repo-you-are-pushing-to>.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
This looks kind of scary. Let’s see how to fix this.

(a)

The first step will be to try to pull in changes before you push. Use git pull <remote> <branch> as needed. If this works, then try to push and everything should be ok.
You might get another error like this:
> git pull origin main
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), 659 bytes | 659.00 KiB/s, done.
From <repo-you-are-pushing-to>
   2417195..8b492ee  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.
which is quite overwhelming.

(b)

Here, the fix is usually pretty easy but I have to teach you a new term. We need to rebase the branch. When a pull happens, Git fetches new commits from GitHub and merges them into your branch (and this merge is actually a commit in itself). The rebase command will temporarily remove your new commits from the commit history, then pull in the new changes and reinstate your commit into the timeline.
If you want to avoid potential large error messages like this again, you might consider changing Git’s default behavior. Instead of fetching and merging, you can do a fast-forward merge which does not do a merge commit. When a fast forward is not possible, the error message is much shorter and then you can use the rebase command to fix things.
To begin this process, first enter git config pull.ff only into your terminal. This will change the default pull behavior for Git (for your current repository only).

(c)

Now try git pull. Things might work. Great! But if you get an error message of fatal: Not possible to fast-forward, aborting., use git pull --rebase to perform a rebase. Then git push back to origin or upstream.
If you ever want to change the default behavior back to what it was, use git config pull.rebase false. If you want to keep that behavior change we just did and you want to do a one-time fetch-merge pull (the old way), use git pull --ff.