Understanding git pull: fetch, merge, and rebase for a linear history
This article explains how git pull works by combining git fetch and git merge, compares merge and rebase strategies, shows how to configure git pull to use rebase for a linear history, and provides practical commands for handling conflicts, stashing, and automatic rebasing.
Background
While working, the author was tagged in a group chat with a screenshot warning not to use merge when pulling code because it makes the commit history complex and hard to trace.
Note! Do not use merge for pulling code!! It makes the commit history very complicated and hard to trace.
The author replied that they used git pull , the colleague said they used rebase , and the author realized they did not fully understand what rebase means.
The big question of git pull
After studying git pull , the author discovered that it is essentially a combination of git fetch and git merge .
git fetch
The git fetch command retrieves the latest commits from a remote repository to the local repository without automatically merging them.
git fetch <remote> <branch>Example: fetch the latest code from the remote named origin .
git fetch origingit merge
The git merge command merges changes from another branch into the current branch. Typically, after git fetch brings in the latest remote changes, git merge integrates them.
git merge <branch>What happens when you run git pull
When there are updates on the remote, executing git pull is equivalent to performing:
git fetch – fetch the latest code from the cloud
git merge – merge the fetched code with the local code
Why git pull can lead to a tangled history
Assume two developers work on the master branch. Both start from node B. One developer quickly creates a new branch and pushes a commit, moving the remote to node C. When the other developer later runs git pull , Git fetches node C and merges it with the local state, creating a new node D. After pushing, the remote now contains a merge commit, resulting in a history with multiple forks and merges that looks very messy.
How to keep a linear git history
The simplest way is to use the rebase command.
What is rebase?
Rebase rewrites the local commits so that they appear on top of the latest remote commits, keeping the history linear.
Using rebase with git pull
You can add the --rebase flag to git pull :
git pull --rebaseAutomatic rebase
To avoid typing the flag each time, set the global configuration:
git config --global pull.rebase trueIf you prefer the default merge behavior, set it to false:
git config --global pull.rebase falseIssues with automatic rebase
Rebase fails if the working directory has uncommitted changes. Resolve this by either committing the changes first or stashing them.
Commit the changes before pulling
Or stash them with git stash
git stash saves uncommitted changes to a stack and restores a clean working directory, useful when switching tasks without committing incomplete code.
git stashAfter pulling, restore the changes:
git stash popHandling conflicts
If a conflict occurs during git pull , resolve the conflict and then continue the rebase with:
git rebase --continueSummary
This article introduced the usage of git pull , explaining that it can operate in two modes: merge (the default) and rebase . Using the merge mode can create a complex, non‑linear history that is hard to maintain. By configuring Git to use rebase (e.g., git config --global pull.rebase true ), developers can keep a clean, linear history and simplify future debugging and code review.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.