KhueApps
Home/DevOps/Fixing Git’s pull warning about divergent branches

Fixing Git’s pull warning about divergent branches

Last updated: October 07, 2025

Overview

Git 2.27+ warns on git pull if you haven’t told it how to handle divergent histories:

  • Merge (default historically): create a merge commit
  • Rebase: replay your local commits on top of upstream
  • Fast-forward only: refuse to merge; only update when no divergence exists

You can silence the warning and set a safe default by configuring one of these behaviors globally or per-repository.

Quickstart (choose one default)

Pick one strategy and set it globally. You can override per repo or per command.

  • Merge (keeps merge commits)
    • Command: git config --global pull.rebase false
  • Rebase (linear history; common for feature branches)
    • Command: git config --global pull.rebase true
    • Optional quality-of-life: git config --global rebase.autoStash true
  • Fast-forward only (CI-safe; refuse implicit merges)
    • Command: git config --global pull.ff only

One-off override when pulling:

  • git pull --rebase
  • git pull --no-rebase
  • git pull --ff-only

Minimal working example (reproduce and fix)

This demonstrates the warning and how to resolve it.

# Terminal A: create a repo and publish it
mkdir demo && cd demo && git init -b main
printf "a\n" > file.txt
git add file.txt && git commit -m "init"
# Create a bare remote to simulate origin
cd .. && git clone --bare demo demo.git
cd demo && git remote add origin ../demo.git && git push -u origin main

# Terminal B: clone elsewhere and diverge
cd .. && git clone demo.git demo-b && cd demo-b
printf "b\n" >> file.txt && git commit -am "b from clone B" && git push

# Terminal A: make a conflicting local commit and pull
cd ../demo
printf "a2\n" >> file.txt && git commit -am "a2 from clone A"
# This pull may warn that you must specify how to reconcile
git pull origin main  # shows the warning on modern Git

# Fix by choosing a policy; e.g., rebase
git config pull.rebase true
# Try again (or future pulls auto-rebase)
git pull --rebase

If you prefer a universal setting, use --global:

git config --global pull.rebase true
# or
git config --global pull.ff only
# or
git config --global pull.rebase false

Choosing a strategy

StrategyBehaviorProsConsRecommended for
MergeCreates a merge commit when both sides changedPreserves exact history; simpleExtra merge commits; noisier git logShared branches where merge commits matter
RebaseReplays local commits atop upstreamLinear history; easier bisect & revertRewrites local commits; care needed on shared branchesFeature/topic branches; daily development
FF-onlyRefuses pulls unless fast-forward possibleAvoids accidental merges; CI-friendlyRequires explicit merge/rebase when divergedCI/CD, protected branches

Step-by-step fixes

  1. Decide a default policy
  • Individual devs often prefer rebase for linear history.
  • CI and protected branches prefer fast-forward only.
  1. Set the default
  • Rebase: git config --global pull.rebase true
  • Merge: git config --global pull.rebase false
  • FF-only: git config --global pull.ff only
  1. Optionally set per-repo policy (overrides global)
# inside the repo
git config pull.rebase true
# or
git config pull.ff only
  1. Use one-off flags when needed
git pull --rebase     # just this time
git pull --no-rebase  # just this time
git pull --ff-only    # just this time
  1. Verify your config and behavior
git config --show-origin --get pull.rebase
git config --show-origin --get pull.ff
git pull --verbose

DevOps recommendations

  • Developer machines: git config --global pull.rebase true; add rebase.autoStash true to reduce conflicts with local changes.
  • CI jobs: Avoid implicit merges. Prefer either:
    • git fetch --tags --prune and then git merge --ff-only origin/main, or
    • git pull --ff-only if you must use pull.
  • Protected release branches: enforce fast-forward merges in server settings and on clients use pull.ff only to block accidental merge commits.

Pitfalls and safeguards

  • Rebasing public commits: Avoid rebasing commits already pushed to shared branches unless your team agrees; it rewrites history and can force others to reconcile.
  • Merge noise: Using merge by default on busy branches can create many merge commits; consider rebase or require PR squashes.
  • FF-only failures: If --ff-only fails, explicitly choose --rebase or create a merge commit via PR to resolve divergence.
  • Work-in-progress changes: With rebase, stash or enable rebase.autoStash true to avoid interruptions.
  • Signed commits: Rebasing re-creates commits; verify signatures if your workflow requires GPG/SSH-signed commits.
  • Submodules: Rebases can be trickier with submodules; update submodules explicitly after pull.
  • Hooks and automation: Ensure client-side hooks don’t assume merge vs rebase; they run at different times.

Performance notes

  • Network first: git pull is fetch + merge/rebase. Most time is network I/O; optimizing fetch (e.g., --depth=1 clones for CI) often yields the biggest gains.
  • Rebase cost: Rebasing replays your local commits; typically cheap if you have few local commits. Large, conflicting series can be slower.
  • Merge cost: Creating a merge commit is O(changes), similar to rebase for small local deltas.
  • Caching: Keep repositories lean; periodically run git gc --aggressive in maintenance windows to reduce pack fragmentation.
  • Shallow workflows (CI): Prefer git clone --depth=1 or git fetch --depth=1 and --ff-only to minimize history transfer.

Troubleshooting

  • Still seeing the warning after setting config? Check scope:
    • Per-command flags override repo config, which overrides global config.
    • Inspect with git config --list --show-origin to find conflicting entries.
  • Undo a rebase in progress: git rebase --abort.
  • Undo after a completed rebase/merge: use git reflog to find the previous HEAD, then git reset --hard <sha> (ensure you won’t lose unpushed work).

FAQ

  • What does “reconcile divergent branches” mean? Your local branch and the remote both have new commits. Git needs to know whether to merge, rebase, or refuse.

  • What’s the safest default for CI? pull.ff only so builds fail fast instead of creating implicit merges.

  • Can I set different policies for different repos? Yes. Omit --global and run git config pull.rebase true (or pull.ff only) inside a repository.

  • How do I silence the warning without changing history behavior? Pick the matching config: Set pull.rebase false to keep merge behavior, or set pull.rebase true to always rebase, or pull.ff only to forbid merges.

  • Does this change server-side behavior? No. These are client-side settings that only affect your git pull.

Series: Git

DevOps