You pulled from git using command git pull origin master
and got a warning –
“Pulling without specifying how to reconcile divergent branches is discouraged“
in this form –
warning: Pulling without specifying how to reconcile divergent branches is discouraged. You can squelch this message by running one of the following commands sometime before your next pull: git config pull.rebase false # merge (the default strategy) git config pull.rebase true # rebase git config pull.ff only # fast-forward only You can replace "git config" with "git config --global" to set a default preference for all repositories. You can also pass --rebase, --no-rebase, or --ff-only on the command line to override the configured default per invocation. remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (4/4), done. remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (4/4), 119.24 KiB | 3.025 MiB/s, done.
This is because a git pull
can create an unexpected merge commit.
The solution and the correct way is to specify how to reconcile the divergent branches. And this can be done by setting either of the configuration –
git config pull.rebase false # OR git config pull.rebase true # OR git config pull.ff only # OR git pull --ff-only
Why, not specifying how to reconcile divergent branches is discouraged?
This is because the git won’t know if merging of remote with local with merge commit is desirable or not.
Let’s understand why the issue is arising.
When we run git pull
, we are actually running two commands – get fetch
and git merge FETCH_HEAD
. This is how the git pull works internally.
The issue is with git merge
because it creates a new commit sha which didn’t exist before. This changes the commit history which is not desirable.
Suppose your current commit graph looks like this –
Now if you perform a git pull origin master
, it will look like this –
Now suppose you are on a different branch and run the command git pull origin master
, then what will happen? GIT will merge remote master branch with your checked out branch, which might not be a desirable outcome.
What will happen by specifying the reconciliation strategy?
A reconciliation strategy will suppress the warning because git will perform the pull according to your instructions. If it has to create the merge commit then it will only proceed if you had allowed it in your strategy. Otherwise, the pull will fail with an error.
There are 3 types of reconciliation strategies –
- Allow merge, i.e. let the push create the merge commit. This is default behavior.
- Rebase – Commit on top of remote branch so that both local and remote be on same page.
- Fast-Forward Only – Proceed only if local branch could fast-forward without creating any extra commit.
How to suppress the warning? (Solution)
Setting any of the below configurations can suppress the warning. But they all have different use cases.
1. Use –ff-only flag
--ff-only
means fast-forward only. It means only update the branch pointer to match the merged branch; do not create a merge commit.
This is the most clean way to pull from remote branch. We recommend you to use this whenever possible.
We can use this flag during pull, like this –
git pull --ff-only origin master
If a branch couldn’t fast-forward, it will throw error –
git pull --ff-only origin master fatal: Not possible to fast-forward, aborting.
2. Change config to use fast-forward only
We can change the configuration and set it to use fast-forward only.
The benefit of this approach is that you don’t need to put --ff-only
flag with each pull. It will automatically set for you.
This approach is similar to --ff-only
flag and we recommend you to use this.
Use this command to change the config –
git config pull.ff only
This will work for current repository only.
If you want to set it for all of the projects then pass --global
flag too –
git config --global pull.ff only
3. Using “Allow Merge” Strategy
This is a default way in which pull works. We don’t need to set anything to function according to this strategy.
But if you want to explicitly set it, then use this command –
git config pull.rebase false # OR git config pull.ff true
4. Using Rebase
Using rebase is a clean solution but not as clean as --ff-only
. Because, although the merge is clean but this approach can mutate the history of your current branch. It won’t prevent the merge to different branch.
You can use the rebase option with this config –
git config pull.rebase true
Again, you can use --global
to set it for all projects.
5. Using no fast-forward
In this approach the fast-forward is forcibly prevented. Every time there will be a merge commit. Even if the branch could fast-forward. We do not recommend this approach.
You can use this with this config command –
git config pull.ff false
Conclusion
Git discourages the pulling of remote branch in divergent local branch without specifying the reconciliation strategy. This can be prevented by using fast-forward approach.
In this article we discussed about multiple strategies for merge commit. You can use any of those and the warning will disappear.
Reference: https://blog.sffc.xyz/post/185195398930/why-you-should-use-git-pull-ff-only