Git Pull

git pull fetches commits from a remote repository and merges them into your current local branch. It’s actually two commands in one — git fetch followed by a merge (or rebase, depending on configuration) — which is exactly why modern Git insists you tell it which reconciliation strategy you want. This is the tenth post in this site’s Git command guide, following Git Push.

Basic Usage

Say your local repository is on main and you want the latest changes from the remote’s feature branch:

$ git pull origin feature

This fetches the feature branch from origin and merges it into whatever branch you currently have checked out. More commonly, you’ll just be syncing your current branch with its own remote counterpart:

$ git pull
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Total 5 (delta 2), reused 5 (delta 2), pack-reused 0
Unpacking objects: 100% (5/5), 1.02 KiB | 522.00 KiB/s, done.
From github.com:username/repo
   3f6a2c1..a92d44e  main       -> origin/main
Updating 3f6a2c1..a92d44e
Fast-forward
 index.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

The Divergent Branches Warning

If you haven’t configured a reconciliation strategy, modern Git (2.27+) prints this warning every time your local and remote branches have both moved forward independently:

$ git pull
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.

Git isn’t broken when you see this — it still completes the pull using the default merge strategy. It’s a deliberate nag, added because silently picking merge over rebase (or vice versa) had been a recurring source of surprise commit graphs. Pick a default and the warning disappears for good:

$ git config --global pull.rebase false

I default to pull.ff only on my own machine — it fast-forwards when possible and simply refuses the pull (rather than auto-merging) when histories have diverged, which forces me to consciously choose rebase or merge instead of letting Git silently create a merge commit I didn’t think about.

Merge vs Rebase Pull

git pull (merge, default)git pull –rebase
History shapeCreates a merge commit joining both historiesReplays your local commits on top of the fetched ones — linear history
Commit graphBranches and merges visible in git log --graphLooks as if you’d made your commits after the latest remote changes, no merge commit
Safety on shared branchesSafe — never rewrites commits that exist elsewhereRewrites your local commit hashes; risky if you’ve already pushed them
Conflict resolutionResolved once, in the merge commitMay require resolving the same conflict multiple times, once per replayed commit

Rebase gives you a cleaner, linear log, but only rebase commits that haven’t been pushed anywhere else — rewriting shared history is exactly the scenario that produces the rejected-push and force-push situations covered in Git Push.

How the Code Works

  • git pull = git fetch (download new commits/refs) + a merge or rebase (integrate them into your current branch).
  • pull.rebase false uses merge — Git’s traditional default, creates a merge commit when histories diverge.
  • pull.rebase true replays your local unpushed commits on top of the fetched ones instead of merging.
  • pull.ff only refuses to pull at all if a fast-forward isn’t possible, forcing you to decide explicitly rather than auto-merging.

FAQs

What’s the difference between git pull and git fetch?

git fetch downloads new commits and updates remote-tracking branches like origin/main, but leaves your current branch untouched. git pull does that, then immediately merges or rebases the fetched changes into your current branch.

Why do I get merge conflicts on pull?

Because the remote and your local branch each changed the same lines of the same file since you last synced. Git can’t automatically decide which version is correct, so it pauses and asks you to resolve the conflict manually before completing the pull.

Is rebase always better than merge for pulling?

No, it’s a tradeoff. Rebase gives a cleaner history but rewrites commit hashes, which is dangerous on a branch others are also pulling from. Many teams default to merge for shared branches and allow rebase only on personal feature branches.

See Also: This Site’s Git Command Guide

This post is part of a 13-part Git command guide on this site:

Conclusion

The divergent-branches warning is one of the more useful nags Git has added in recent years — it’s pushing you toward an explicit decision you were making implicitly anyway. Set pull.rebase or pull.ff once, globally, and move on. Once your local branch is current, reviewing what actually changed is next, in Git Log.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.