Pulling without specifying how to reconcile divergent branches discouraged

Total
0
Shares

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 –

local and remote before diverged git pull
Source: https://blog.sffc.xyz/post/185195398930/why-you-should-use-git-pull-ff-only

Now if you perform a git pull origin master, it will look like this –

local master after git pull on diverged branch
Source: https://blog.sffc.xyz/post/185195398930/why-you-should-use-git-pull-ff-only

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 –

  1. Allow merge, i.e. let the push create the merge commit. This is default behavior.
  2. Rebase – Commit on top of remote branch so that both local and remote be on same page.
  3. 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