Pull with Rebase
git pull --rebase is the cleaner cousin of git pull. Instead of merging the remote into your branch (which creates a merge commit), it rebases your local commits on top of the latest remote state. The result is a straight, linear history with no “Merge branch” noise.
What it does
Before pull
Local: A───B───C───X───Y (X, Y are your local commits) Remote: A───B───C───D───E (D, E are commits others pushed)
After 'git pull --rebase'
Local: A───B───C───D───E───X'───Y' X and Y are replayed onto E as X' and Y'. No merge commit. Linear history.
The command
git pull --rebase # Equivalent to: git fetch git rebase origin/<current-branch>
Why use it
Linear history. No
Merge branch ...commits cluttering your log.Easier code review. Your branch looks like it’s always been built on the latest base.
Cleaner bisects. Linear history makes
git bisectfind bugs reliably.Honest local commits. Your commits land on top of the latest remote — there’s no question what they were “based on”.
When NOT to use it
When the branch is shared and others may have pulled your previous commits. Rebasing rewrites them — see the “Golden Rule of Rebasing” page.
For a
main-style branch with deliberate--no-ffmerge commits (Gitflow).When you specifically want a visible merge commit recording the integration point.
Make it your default
Set globally
git config --global pull.rebase true # Now every 'git pull' is actually 'git pull --rebase'
Or per-branch
git config branch.feature-x.rebase true
Conflicts during pull --rebase
Each replayed commit can conflict separately. The resolution is the standard rebase loop: edit, git add, then git rebase --continue. To bail out completely: git rebase --abort.
A conflict during pull --rebase
git pull --rebase # Auto-merging src/app.js # CONFLICT (content): Merge conflict in src/app.js # error: could not apply 1f9ab2c... Add login # Resolve, then: git add src/app.js git rebase --continue # Or give up: git rebase --abort
Auto-stashing uncommitted work
Handle local edits gracefully
# Without --autostash, pull --rebase refuses if you have uncommitted changes. git pull --rebase --autostash # Or set as default: git config --global rebase.autoStash true
pull --rebase vs pull --ff-only
pull --rebase— always integrates; rebases if needed; never creates a merge commit.pull --ff-only— refuses to integrate unless fast-forward is possible. Forces you to think when histories diverged.Many teams set
pull.ff=onlyto enforce: “If FF won’t work, rebase or merge manually.”
Visualising the difference
git pull (default merge)
Local: A───B───C───X───Y───M ◀── main
\ /
Remote: ─D───E─────────────┘git pull --rebase
Local: A───B───C───D───E───X'───Y' ◀── main (No merge commit; your work replayed onto remote tip)
Recommended setup
The 'nice and tidy' team config
git config --global pull.rebase true git config --global rebase.autoStash true git config --global rerere.enabled true git config --global fetch.prune true
With these four, git pull becomes a one-shot keep-my-branch-current command:
Fetch + rebase (no merge commit).
Auto-stash and restore uncommitted work.
Remember and replay conflict resolutions.
Auto-prune deleted remote branches.
pull.rebase true, your team’s history on shared branches looks dramatically cleaner — often after just a week or two. Try it.