Fetching, Rebasing, and Cherry-picking
Working on a team means constantly synchronizing with others. This lesson covers the commands for staying up-to-date without losing your work.
Git Fetch
Fetch downloads remote changes without modifying your working tree.
bash1$ git fetch origin2From github.com:team/project3 * [new branch] feature/api -> origin/feature/api4 1a2b3c4..5d6e7f8 main -> origin/main
Fetch vs Pull
| Command | Action |
|---|---|
git fetch | Download changes only |
git pull | Fetch + merge/rebase |
Fetch is safer—it lets you inspect changes before integrating them:
bash1$ git fetch origin2$ git log main..origin/main --oneline # See what's new3$ git merge origin/main # Then merge
Fetch All Remotes
bash1$ git fetch --all
Rebasing
Rebase replays your commits on top of another branch, creating a linear history.
Why Rebase?
Compare merge vs rebase:
Merge creates a merge commit:
1main: A---B-------M2 \ /3feature: C---D
Rebase creates linear history:
main: A---B---C'---D'
Basic Rebase
bash1$ git checkout feature-branch2$ git rebase main3First, rewinding head to replay your work on top of it...4Applying: Add feature X5Applying: Fix bug in feature X
Pull with Rebase
Instead of creating merge commits when pulling:
bash1$ git pull --rebase origin main
This is equivalent to:
bash1$ git fetch origin2$ git rebase origin/main
Rebase Workflow
Keep your feature branch up-to-date:
bash1# 1. Switch to feature branch2$ git checkout feature/my-feature34# 2. Fetch latest changes5$ git fetch origin67# 3. Rebase onto updated main8$ git rebase origin/main910# 4. Force-push if already pushed11$ git push --force-with-lease origin feature/my-feature
When to Rebase vs Merge
| Scenario | Use |
|---|---|
| Updating feature branch with main | Rebase |
| Integrating feature into main | Merge (via PR) |
| Public/shared branches | Merge (avoid rewriting history) |
| Personal branches not yet pushed | Rebase freely |
Golden Rule of Rebasing
Never rebase commits that have been pushed to a shared branch.
Rebasing rewrites history. If others have based work on your commits, rebasing causes divergence and confusion.
Cherry-picking
Cherry-pick copies a specific commit from one branch to another.
Basic Cherry-pick
bash1$ git cherry-pick 5d6e7f82[main 9a0b1c2] Fix critical bug3 Date: Sun Nov 30 10:00:00 2025 +00004 1 file changed, 2 insertions(+)
When to Cherry-pick
- Apply a hotfix from a feature branch to main
- Backport a fix to a release branch
- Pull specific work without merging entire branch
Cherry-pick Multiple Commits
bash1# Specific commits2$ git cherry-pick abc123 def45634# Range of commits5$ git cherry-pick abc123..def456
Cherry-pick Without Committing
Stage the changes but don't commit:
bash1$ git cherry-pick -n 5d6e7f8
This lets you modify the changes before committing.
Handling Conflicts
Both rebase and cherry-pick can cause conflicts.
During Rebase
bash1$ git rebase origin/main2Auto-merging app.js3CONFLICT (content): Merge conflict in app.js4error: could not apply abc123... Feature X
Resolution:
bash1# 1. Fix the conflict in app.js2$ vim app.js34# 2. Stage the resolution5$ git add app.js67# 3. Continue rebase8$ git rebase --continue
Or abort:
bash1$ git rebase --abort
During Cherry-pick
bash1$ git cherry-pick 5d6e7f82error: could not apply 5d6e7f8... Fix bug
Resolution:
bash1$ vim conflicted-file.js2$ git add conflicted-file.js3$ git cherry-pick --continue
Force Push Safely
After rebasing a pushed branch, you need to force push:
bash1# Safe: Checks that remote hasn't changed2$ git push --force-with-lease origin feature-branch34# Unsafe: Overwrites unconditionally5$ git push --force origin feature-branch
Always use --force-with-lease to avoid overwriting teammates' work.
Key Commands Summary
| Command | Purpose |
|---|---|
git fetch origin | Download remote changes |
git pull --rebase | Fetch and rebase |
git rebase main | Replay commits on main |
git cherry-pick SHA | Copy specific commit |
git push --force-with-lease | Safe force push |
Key Takeaway
Use fetch to see what's new, rebase to keep feature branches linear, and cherry-pick for targeted commit copies. Never rebase shared branches, and use --force-with-lease when force pushing.