Pulling (git pull)

git pull is a convenience command that runs git fetch followed by an integrate step (merge by default, or rebase) of the upstream branch into your current branch.

Why it matters

It is the everyday “get the latest” command, but unlike fetch it edits your working tree and can create merge commits or conflicts. Knowing it is fetch + merge (or fetch + rebase) is what lets you predict its outcome and choose a clean history over noisy merge bubbles on shared branches.

How it works

git pull reads the current branch’s upstream, fetches it, then integrates FETCH_HEAD into HEAD. The integrate mode is governed by pull.rebase and pull.ff.

pull.rebasepull.ffBehavior when diverged
false (default)truefast-forward if possible, else merge commit
falseonlyfast-forward or abort (no merge commit)
truen/areplay your local commits on top (linear)
mergesn/arebase but preserve real merge commits
  • Fast-forward — if you have no local commits, main just slides up to origin/main; no merge commit.
  • Diverged — both sides committed: a merge creates a commit with two parents; a rebase rewrites your local commits onto the new tip.
  • Since Git 2.27, pull warns until you pick a strategy; set it explicitly to avoid the prompt.

Example

$ git config pull.rebase true     # team prefers linear history
$ git pull
From github.com:acme/api
   9f2c1ab..a71be09  main -> origin/main
First, rewinding head to replay your work on top of it...
Applying: feat: pagination          # your commit re-applied after theirs
$ git log --oneline -3
b9d4f02 feat: pagination            # rebased: new SHA, now atop a71be09
a71be09 fix: retry on 503
9f2c1ab feat: add health check

Pitfalls

  • Accidental merge bubbles — default merge mode on a shared branch litters history with “Merge branch ‘main’” commits; prefer pull.rebase=true or --ff-only.
  • Rebasing pulled-then-pushed commitspull --rebase rewrites SHAs of unpushed local commits; never rebase commits already shared (see rebasing-git-rebase).
  • Dirty tree blocks pull — uncommitted changes that conflict abort the operation; stash or commit first.
  • pull hides the fetch — you lose the chance to inspect origin/main before integrating; fetch + review is safer on critical branches.

See also