Git Fetch & Pull
Understanding the difference between git fetch and git pull is crucial for effective collaboration. These commands help you synchronize your local repository with remote repositories.
The Key Difference
git fetch: Downloads changes but doesn't merge themgit pull: Downloads changes AND merges them (fetch + merge)
Think of it as:
- Fetch = "Show me what's new"
- Pull = "Get what's new and apply it"
Git Fetch
Basic Fetch
Download changes from the remote repository without merging:
git fetchThis updates your remote-tracking branches (like origin/main) but doesn't change your working directory.
Example:
$ git fetch
remote: Counting objects: 10, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 10 (delta 5), reused 0 (delta 0)
Unpacking objects: 100% (10/10), done.
From https://github.com/user/repo
abc123..def456 main -> origin/mainFetch Specific Remote
# Fetch from specific remote
git fetch origin
# Fetch from different remote
git fetch upstreamFetch Specific Branch
# Fetch only a specific branch
git fetch origin main
# Fetch multiple branches
git fetch origin main developFetch All Remotes
# Fetch from all configured remotes
git fetch --allFetch with Prune
Remove remote-tracking branches that no longer exist on the remote:
git fetch --prune
# or shorthand
git fetch -pExample:
$ git fetch --prune
From https://github.com/user/repo
- [deleted] (none) -> origin/old-feature
abc123..def456 main -> origin/mainDry Run Fetch
See what would be fetched without actually fetching:
git fetch --dry-runAfter Fetching
Check What Was Fetched
# See remote branches
git branch -r
# See all branches (local and remote)
git branch -a
# View fetched changes
git log origin/main
# Compare with your branch
git diff main origin/mainMerge Fetched Changes
# After fetch, merge manually
git fetch origin
git merge origin/main
# Or merge specific remote branch
git merge origin/feature-branchView Fetched Commits
# See new commits from remote
git log main..origin/main
# See what changed
git diff main origin/mainGit Pull
Basic Pull
Fetch and merge changes from remote in one command:
git pullThis is equivalent to:
git fetch
git merge origin/current-branchExample:
$ git pull
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From https://github.com/user/repo
abc123..def456 main -> origin/main
Updating abc123..def456
Fast-forward
file.txt | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)Pull from Specific Remote and Branch
# Pull from specific remote and branch
git pull origin main
# Pull from upstream
git pull upstream mainPull with Rebase
Pull changes and rebase instead of merge:
git pull --rebaseThis is equivalent to:
git fetch
git rebase origin/current-branchWhy use rebase?
- Creates linear history
- Avoids merge commits
- Cleaner project history
Example:
$ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: Your local commitPull All Branches
# Pull and update all tracking branches
git pull --allPull with Fast-Forward Only
Refuse to pull if fast-forward isn't possible:
git pull --ff-onlyIf merge is required, the pull will fail. This prevents accidental merge commits.
Pull Quietly
Suppress detailed output:
git pull --quiet
# or
git pull -qPull with Specific Strategy
# Pull with specific merge strategy
git pull --strategy=ours
# Pull preferring their changes on conflict
git pull -X theirsPull vs Fetch: When to Use Each
Use Fetch When:
✅ You want to see changes before merging
✅ You're reviewing what others have pushed
✅ You want to compare branches first
✅ You're not ready to integrate changes
✅ You want more control over the process
Example workflow:
# Fetch changes
git fetch origin
# Review changes
git log origin/main
# Compare with your branch
git diff main origin/main
# Decide to merge or not
git merge origin/mainUse Pull When:
✅ You trust the remote branch
✅ You want to quickly sync
✅ You're alone on the branch
✅ You want convenience
✅ Fast-forward merge is likely
Example workflow:
# Quick sync with remote
git pull origin mainCommon Workflows
Workflow 1: Safe Update (Fetch First)
# 1. Fetch changes
git fetch origin
# 2. Check what changed
git log --oneline main..origin/main
# 3. Review differences
git diff main origin/main
# 4. Merge if satisfied
git merge origin/mainWorkflow 2: Quick Update (Pull)
# Quick pull when you're confident
git pull origin mainWorkflow 3: Pull with Rebase
# Pull and rebase your commits on top
git pull --rebase origin main
# If conflicts occur, resolve and continue
git add .
git rebase --continueWorkflow 4: Sync Fork from Upstream
# Add upstream remote (once)
git remote add upstream https://github.com/original/repo.git
# Fetch from upstream
git fetch upstream
# Merge upstream changes
git checkout main
git merge upstream/main
# Push to your fork
git push origin mainWorkflow 5: Update All Branches
# Fetch all remotes
git fetch --all --prune
# Switch to main and pull
git checkout main
git pull
# Switch to develop and pull
git checkout develop
git pullHandling Pull Conflicts
When Pull Conflicts Occur
$ git pull
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.Resolving Pull Conflicts
Step 1: Check status
git statusStep 2: Edit conflicted files
- Look for conflict markers
- Choose or combine changes
- Save files
Step 3: Stage resolved files
git add file.txtStep 4: Complete the merge
git commitAborting a Pull
# Cancel the pull and return to previous state
git merge --abortAdvanced Fetch & Pull Techniques
Fetch Specific Refs
# Fetch specific reference
git fetch origin refs/heads/main:refs/remotes/origin/main
# Fetch pull request (GitHub)
git fetch origin pull/123/head:pr-123Pull with Autostash
Automatically stash and re-apply local changes:
git pull --rebase --autostashThis is useful when you have uncommitted changes.
Configure Default Pull Behavior
# Set default to rebase instead of merge
git config --global pull.rebase true
# Set to fast-forward only
git config --global pull.ff only
# Return to default (merge)
git config --global pull.rebase falseFetch Tags
# Fetch all tags
git fetch --tags
# Fetch without tags
git fetch --no-tagsShallow Fetch
Fetch limited history:
# Fetch only last commit
git fetch --depth 1
# Fetch last 10 commits
git fetch --depth 10Checking Remote Status
See What's Different
# After fetch, see what's ahead/behind
git status
# Example output:
# Your branch is behind 'origin/main' by 3 commits
# Your branch is ahead of 'origin/main' by 2 commits
# Your branch and 'origin/main' have divergedCompare with Remote
# See commits in remote but not in local
git log main..origin/main
# See commits in local but not in remote
git log origin/main..main
# See differences in both
git log main...origin/mainView Remote Branches
# List remote branches
git branch -r
# List all branches with tracking info
git branch -vv
# Show remote branches with last commit
git branch -r -vTroubleshooting
Pull Rejected (Non-Fast-Forward)
$ git pull
error: Your local changes to the following files would be overwritten by merge:
file.txt
Please commit your changes or stash them before you merge.
AbortingSolution:
# Option 1: Commit your changes
git add .
git commit -m "Your message"
git pull
# Option 2: Stash your changes
git stash
git pull
git stash pop
# Option 3: Force pull (DANGER: loses local changes)
git fetch origin
git reset --hard origin/mainDiverged Branches
$ git status
Your branch and 'origin/main' have diverged,
and have 2 and 3 different commits each, respectively.Solution:
# Option 1: Merge
git pull
# Option 2: Rebase
git pull --rebase
# Option 3: Reset to remote (lose local commits)
git reset --hard origin/mainBehind Remote
# Your branch is behind, just pull
git pullAhead of Remote
# Your branch is ahead, push your changes
git pushBest Practices
1. Fetch Regularly
# Fetch every morning
git fetch --all --prune2. Review Before Merging
# Don't blindly pull, check first
git fetch
git log main..origin/main
git pull3. Use Pull Rebase for Clean History
# Configure once
git config --global pull.rebase true
# Or use per pull
git pull --rebase4. Keep Branches Updated
# Regularly sync main branch
git checkout main
git pull origin main5. Handle Conflicts Promptly
Don't let conflicts linger. Resolve them as soon as they occur.
Configuration Tips
Set Default Remote
# Set upstream tracking branch
git branch --set-upstream-to=origin/main main
# Now simple git pull works
git pullAuto-Prune on Fetch
# Always prune deleted branches
git config --global fetch.prune trueSet Pull Strategy
# Always use rebase
git config --global pull.rebase true
# Use fast-forward only
git config --global pull.ff onlySummary
Git Fetch:
- ✅ Safe - doesn't change your files
- ✅ Review changes before merging
- ✅ More control over integration
- ✅ Great for checking updates
Git Pull:
- ✅ Convenient - fetch and merge in one
- ✅ Quick synchronization
- ✅ Good for trusted sources
- ✅ Can use with rebase for clean history
Key Takeaways:
fetch= download without mergingpull= fetch + mergepull --rebase= fetch + rebase- Use
fetchwhen you want to review first - Use
pullwhen you want quick sync - Configure
pull.rebasefor cleaner history
See Also
- Git Remote - Managing remotes
- Git Merge - Merging strategies
- Git Rebase - Rebasing changes
- Git Push - Pushing changes
- Git Branch - Branch management