Fetch vs Pull
Understanding the difference between fetch and pull is crucial for working with remote repositories effectively.
The Key Difference
| Command | What it does |
|---|---|
git fetch | Downloads changes, doesn't integrate |
git pull | Downloads changes AND merges them |
git pull = git fetch + git merge
Git Fetch
Fetch downloads remote changes without affecting your working directory:
git fetch origin
What Fetch Does
- Contacts the remote repository
- Downloads any new commits
- Updates remote-tracking branches (e.g.,
origin/main) - Does NOT change your local branches
- Does NOT change your working directory
Before fetch:
Local main: A ← B ← C
origin/main: A ← B ← C
Remote main: A ← B ← C ← D ← E
After fetch:
Local main: A ← B ← C (unchanged!)
origin/main: A ← B ← C ← D ← E (updated)
Remote main: A ← B ← C ← D ← E
Why Use Fetch?
- Safe: Won't mess up your current work
- Preview: See what changed before integrating
- Control: Decide when and how to integrate
Fetch Commands
# Fetch all branches from origin
git fetch origin
# Fetch specific branch
git fetch origin main
# Fetch from all remotes
git fetch --all
# Fetch and prune deleted branches
git fetch --prune
# Fetch tags
git fetch --tags
After Fetching
View what was fetched:
# See the difference
git log main..origin/main
# See what commits are new
git log --oneline origin/main ^main
# View the changes
git diff main origin/main
Then integrate when ready:
# Merge the fetched changes
git merge origin/main
# Or rebase
git rebase origin/main
Git Pull
Pull combines fetch and merge in one command:
git pull origin main
What Pull Does
- Fetches changes from remote (like
git fetch) - Merges them into your current branch (like
git merge)
Before pull:
Local main: A ← B ← C
origin/main: A ← B ← C
Remote main: A ← B ← C ← D ← E
After pull (fetch + merge):
Local main: A ← B ← C ← ← ← M
\ /
D ← E
origin/main: A ← B ← C ← D ← E
Remote main: A ← B ← C ← D ← E
Pull with Rebase
git pull --rebase origin main
Instead of merging, rebases your local commits on top:
After pull --rebase:
Local main: A ← B ← C ← D ← E ← C'
↑
origin/main
Your commit C is replayed as C' after D and E.
When to Use Each
Use Fetch When
- You want to see what changed before integrating
- You're not sure if you want to integrate yet
- You want to integrate differently (rebase vs merge)
- You want to compare branches before merging
- You're working on something delicate and don't want surprises
git fetch origin
git log --oneline main..origin/main # What's new?
git diff main origin/main # What changed?
# Looks good, now merge
git merge origin/main
Use Pull When
- You just want the latest changes quickly
- You trust the remote changes
- You're starting fresh work and need to update first
- Simple workflow with no local uncommitted work
git pull origin main
# Done!
Exercise: Fetch vs Pull
Practice understanding the difference between fetch and pull:
Comparing Branches After Fetch
# Commits on remote that you don't have
git log main..origin/main
# Commits you have that remote doesn't
git log origin/main..main
# Both directions (symmetric difference)
git log main...origin/main
# Files changed
git diff --stat main origin/main
# Specific file comparison
git diff main origin/main -- path/to/file.js
The Fetch-Then-Merge Workflow
A safer alternative to pull:
# 1. Fetch changes
git fetch origin
# 2. Review what's new
git log --oneline main..origin/main
git diff main origin/main
# 3. If everything looks good, merge
git merge origin/main
# 4. Or rebase for cleaner history
git rebase origin/main
Pull Conflicts
If pull encounters conflicts:
git pull origin main
# CONFLICT!
# Resolve conflicts
# Edit files to fix conflicts
git add .
git commit
With rebase:
git pull --rebase origin main
# CONFLICT!
# Resolve conflicts
git add .
git rebase --continue
Configuring Pull Behavior
# Always rebase instead of merge
git config --global pull.rebase true
# Only pull if fast-forward is possible
git config --global pull.ff only
# Warn if pull would create merge commit
git config --global pull.rebase merges
Fetch vs Pull Summary
┌─────────────────────────────────────────────────────┐
│ FETCH │
├─────────────────────────────────────────────────────┤
│ ✓ Downloads changes │
│ ✓ Updates remote-tracking branches │
│ ✗ Does NOT modify local branches │
│ ✗ Does NOT modify working directory │
│ → Safe, non-destructive │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ PULL │
├─────────────────────────────────────────────────────┤
│ ✓ Downloads changes (fetch) │
│ ✓ Integrates changes (merge or rebase) │
│ ✓ Updates local branch │
│ ✓ Updates working directory │
│ → Convenient, but can cause conflicts │
└─────────────────────────────────────────────────────┘
Summary
git fetchdownloads without integrating (safe to run anytime)git pulldownloads and integrates (fetch + merge)- Use fetch when you want to review changes first
- Use pull when you want quick updates
git pull --rebasecreates cleaner history- After fetch, use
git logandgit diffto see what changed
In the next lesson, we'll learn about tracking branches.

