fix: cleanup cherry-picking tasks and tips
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Module 09: Cherry-Pick
|
||||
# Module 05: Cherry-Pick
|
||||
|
||||
## Learning Objectives
|
||||
|
||||
@@ -6,155 +6,358 @@ By the end of this module, you will:
|
||||
- Understand what cherry-picking is and how it works
|
||||
- Know when to use cherry-pick vs merge or rebase
|
||||
- Apply specific commits from one branch to another
|
||||
- Handle cherry-pick conflicts if they occur
|
||||
- Understand common use cases for cherry-picking
|
||||
- Learn how cherry-pick creates new commits with different hashes
|
||||
|
||||
## Challenge Description
|
||||
## Setup
|
||||
|
||||
You have a `development` branch with several commits. Some of these commits are bug fixes that need to be applied to the `main` branch immediately, but other commits are experimental features that shouldn't be merged yet.
|
||||
Create the challenge environment:
|
||||
|
||||
Your task is to:
|
||||
1. Review the commits on the development branch
|
||||
2. Identify which commits are bug fixes
|
||||
3. Cherry-pick only the bug fix commits to the main branch
|
||||
4. Verify that main has the bug fixes but not the experimental features
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### What is Cherry-Pick?
|
||||
|
||||
Cherry-pick allows you to apply a specific commit from one branch to another. Instead of merging an entire branch, you can selectively choose individual commits.
|
||||
|
||||
```
|
||||
A---B---C---D development
|
||||
/
|
||||
E---F main
|
||||
```pwsh
|
||||
.\setup.ps1
|
||||
```
|
||||
|
||||
After cherry-picking commit C:
|
||||
```
|
||||
A---B---C---D development
|
||||
/
|
||||
E---F---C' main
|
||||
This creates a repository with a `development` branch containing both bug fixes and experimental features.
|
||||
|
||||
## Overview
|
||||
|
||||
**Cherry-pick** allows you to copy specific commits from one branch to another. Unlike merging (which brings ALL commits), cherry-pick lets you be surgical about exactly which changes you want to apply.
|
||||
|
||||
Think of it like picking cherries from a tree - you select only the ripe ones you want, leaving the rest behind.
|
||||
|
||||
### Why Use Cherry-Pick?
|
||||
|
||||
- **Selective deployment** - Apply critical bug fixes without merging unfinished features
|
||||
- **Hotfixes** - Quickly move a fix from development to production
|
||||
- **Backporting** - Apply fixes to older release branches
|
||||
- **Wrong branch** - Move commits you accidentally made on the wrong branch
|
||||
- **Duplicate commits** - Apply the same fix across multiple branches
|
||||
|
||||
## Your Task
|
||||
|
||||
### The Scenario
|
||||
|
||||
You're working on a project where:
|
||||
- The `main` branch is stable and in production
|
||||
- The `development` branch has new features being tested
|
||||
- Development has critical bug fixes that need to go to production NOW
|
||||
- But development also has experimental features that aren't ready yet
|
||||
|
||||
You need to cherry-pick ONLY the bug fixes to main, leaving the experimental features behind.
|
||||
|
||||
### Part 1: Explore the Development Branch
|
||||
|
||||
First, see what commits are on the development branch:
|
||||
|
||||
```pwsh
|
||||
cd challenge
|
||||
|
||||
# View all commits on development branch
|
||||
git log --oneline development
|
||||
|
||||
# View the full commit graph
|
||||
git log --oneline --graph --all
|
||||
```
|
||||
|
||||
Note that C' is a new commit with the same changes as C but a different commit hash.
|
||||
**Study the commits:**
|
||||
- Look for commits with "Fix" in the message (these are bug fixes)
|
||||
- Look for commits with "experimental" or "beta" (these should stay on development)
|
||||
- Note the commit hashes (the 7-character codes like `abc1234`)
|
||||
|
||||
### Cherry-Pick vs Merge vs Rebase
|
||||
|
||||
- **Merge**: Brings all commits from another branch and creates a merge commit
|
||||
- **Rebase**: Replays all commits from your branch on top of another branch
|
||||
- **Cherry-Pick**: Applies one or more specific commits to your current branch
|
||||
|
||||
### When to Use Cherry-Pick
|
||||
|
||||
Cherry-pick is useful when you:
|
||||
- Need a bug fix from a feature branch but can't merge the whole branch yet
|
||||
- Want to apply a specific commit to a release branch
|
||||
- Need to backport a fix to an older version
|
||||
- Made a commit on the wrong branch and need to move it
|
||||
- Want to duplicate a commit across multiple branches
|
||||
|
||||
### Cherry-Pick Creates New Commits
|
||||
|
||||
Important: Cherry-picked commits are new commits with different hashes. The original commit remains on the source branch, and a copy is created on the target branch with the same changes but a different commit ID.
|
||||
|
||||
## Useful Commands
|
||||
|
||||
```bash
|
||||
# View commits on another branch
|
||||
git log <branch-name> --oneline
|
||||
|
||||
# View a specific commit's details
|
||||
**Inspect specific commits:**
|
||||
```pwsh
|
||||
# See what files a commit changed
|
||||
git show <commit-hash>
|
||||
|
||||
# Example:
|
||||
# git show abc1234
|
||||
```
|
||||
|
||||
You should see:
|
||||
- 2 commits that fix bugs (security and performance)
|
||||
- 2 commits that add experimental features
|
||||
|
||||
### Part 2: Switch to Main Branch
|
||||
|
||||
Before cherry-picking, you need to be on the target branch (main):
|
||||
|
||||
```pwsh
|
||||
# Switch to main branch
|
||||
git switch main
|
||||
|
||||
# Verify you're on main
|
||||
git branch
|
||||
```
|
||||
|
||||
The `*` should be next to `main`.
|
||||
|
||||
**Check what's currently on main:**
|
||||
```pwsh
|
||||
# See main's commits
|
||||
git log --oneline
|
||||
|
||||
# See what files exist
|
||||
ls
|
||||
```
|
||||
|
||||
Main should only have the initial app and README - no bug fixes yet, no experimental features.
|
||||
|
||||
### Part 3: Cherry-Pick the Bug Fixes
|
||||
|
||||
Now copy the bug fix commits from development to main:
|
||||
|
||||
1. Find the security fix commit hash by looking at your earlier `git log --oneline --graph --all`
|
||||
- Look for a commit message like "Fix security vulnerability in input validation"
|
||||
- Note its hash (first 7 characters)
|
||||
|
||||
2. Cherry-pick the security fix:
|
||||
```pwsh
|
||||
git cherry-pick <security-fix-hash>
|
||||
|
||||
# Example if the hash is abc1234:
|
||||
# git cherry-pick abc1234
|
||||
```
|
||||
3. Verify it worked: Check that security.py, with `ls` or check your file explorer in VSCode, now exists and check that the commit has been added to the main branch with `git log --oneline --graph --all`
|
||||
4. Find the performance fix commit hash
|
||||
- Look for "Fix performance issue with data caching"
|
||||
- Note its hash
|
||||
|
||||
5. Cherry-pick the performance fix:
|
||||
```pwsh
|
||||
git cherry-pick <performance-fix-hash>
|
||||
```
|
||||
|
||||
6. Verify both fixes are now on main:
|
||||
```pwsh
|
||||
# You should see both security.py and cache.py
|
||||
ls
|
||||
|
||||
# View the graph showing both branches
|
||||
git log --oneline --graph --all
|
||||
```
|
||||
|
||||
### Part 4: Verify Your Solution
|
||||
|
||||
Check that you completed the challenge correctly:
|
||||
|
||||
```pwsh
|
||||
# From inside the module directory
|
||||
.\verify.ps1
|
||||
```
|
||||
|
||||
The verification checks:
|
||||
- ✅ You're on the main branch
|
||||
- ✅ Security fix is applied to main
|
||||
- ✅ Performance fix is applied to main
|
||||
- ✅ Experimental features are NOT on main
|
||||
- ✅ Development branch still has all commits
|
||||
|
||||
## Understanding Cherry-Pick
|
||||
|
||||
### What Actually Happens?
|
||||
|
||||
When you cherry-pick a commit, Git:
|
||||
1. Looks at what changed in that specific commit
|
||||
2. Applies those same changes to your current branch
|
||||
3. Creates a NEW commit with those changes
|
||||
|
||||
```
|
||||
Before cherry-pick:
|
||||
|
||||
development: A---B---C---D
|
||||
/
|
||||
main: E---F
|
||||
|
||||
After: git switch main && git cherry-pick C
|
||||
|
||||
development: A---B---C---D
|
||||
/
|
||||
main: E---F---C'
|
||||
```
|
||||
|
||||
Notice:
|
||||
- `C'` is a NEW commit (different hash than original `C`)
|
||||
- Original `C` still exists on development
|
||||
- Main now has the changes from C, but not B or D
|
||||
|
||||
### Cherry-Pick vs Merge
|
||||
|
||||
**Merge brings everything:**
|
||||
```pwsh
|
||||
git switch main
|
||||
git merge development
|
||||
# Result: A, B, C, and D all come to main
|
||||
```
|
||||
|
||||
**Cherry-pick is selective:**
|
||||
```pwsh
|
||||
git switch main
|
||||
git cherry-pick C
|
||||
# Result: Only C comes to main (as C')
|
||||
```
|
||||
|
||||
### Important: New Commits, New Hashes
|
||||
|
||||
Cherry-picked commits are COPIES, not moves:
|
||||
- Original commit stays on source branch
|
||||
- New commit created on target branch
|
||||
- Different commit hash (because different parent)
|
||||
- Same changes, same message, different identity
|
||||
|
||||
## Key Commands
|
||||
|
||||
### Viewing Commits
|
||||
|
||||
```pwsh
|
||||
# See commits on another branch
|
||||
git log branch-name --oneline
|
||||
|
||||
# See what a specific commit changed
|
||||
git show <commit-hash>
|
||||
|
||||
# See commit graph
|
||||
git log --oneline --graph --all
|
||||
|
||||
# See only commit message (not changes)
|
||||
git log --oneline
|
||||
```
|
||||
|
||||
### Cherry-Picking
|
||||
|
||||
```pwsh
|
||||
# Cherry-pick a single commit
|
||||
git cherry-pick <commit-hash>
|
||||
|
||||
# Cherry-pick multiple commits
|
||||
git cherry-pick <commit-hash1> <commit-hash2>
|
||||
# Cherry-pick multiple commits (in order)
|
||||
git cherry-pick <hash1> <hash2> <hash3>
|
||||
|
||||
# Cherry-pick a range of commits
|
||||
git cherry-pick <start-hash>..<end-hash>
|
||||
|
||||
# If conflicts occur during cherry-pick:
|
||||
# 1. Resolve conflicts in files
|
||||
# 2. Stage the resolved files
|
||||
git add <file>
|
||||
# 3. Continue the cherry-pick
|
||||
git cherry-pick --continue
|
||||
|
||||
# Abort a cherry-pick if something goes wrong
|
||||
git cherry-pick --abort
|
||||
|
||||
# View commit history graph
|
||||
git log --oneline --graph --all
|
||||
```
|
||||
|
||||
## Verification
|
||||
### After Cherry-Pick
|
||||
|
||||
Run the verification script to check your solution:
|
||||
```pwsh
|
||||
# Verify the commit was added
|
||||
git log --oneline
|
||||
|
||||
```bash
|
||||
.\verify.ps1
|
||||
# See what files changed
|
||||
git show HEAD
|
||||
|
||||
# Compare branches
|
||||
git log main..development --oneline
|
||||
```
|
||||
|
||||
The verification will check that:
|
||||
- You're on the main branch
|
||||
- The security bug fix commit has been applied to main
|
||||
- The performance bug fix commit has been applied to main
|
||||
- The experimental features are NOT on main
|
||||
- The commits were cherry-picked (not merged)
|
||||
|
||||
## Challenge Steps
|
||||
|
||||
1. Navigate to the challenge directory
|
||||
2. You're currently on the development branch
|
||||
3. View the commits: `git log --oneline`
|
||||
4. You'll see several commits - identify the bug fixes
|
||||
5. Switch to main branch: `git switch main`
|
||||
6. Cherry-pick the bug fix commits (you'll need their commit hashes)
|
||||
7. Verify the result with `git log --oneline`
|
||||
8. Run the verification script
|
||||
|
||||
## Tips
|
||||
|
||||
- Use `git log development --oneline` to see commits on the development branch
|
||||
- Use `git show <hash>` to view details of a specific commit
|
||||
- You can cherry-pick by commit hash - you only need the first 7 characters
|
||||
- Cherry-pick commits in chronological order (oldest first) to avoid conflicts
|
||||
- If you make a mistake, use `.\reset.ps1` to start over
|
||||
- The commit message will be preserved when cherry-picking
|
||||
|
||||
## Common Cherry-Pick Scenarios
|
||||
## Common Workflows
|
||||
|
||||
### Hotfix to Production
|
||||
You have a critical bug fix on a development branch that needs to go to production immediately:
|
||||
```bash
|
||||
git switch production
|
||||
git cherry-pick <bugfix-commit-hash>
|
||||
```
|
||||
|
||||
### Wrong Branch
|
||||
You accidentally committed on the wrong branch:
|
||||
```bash
|
||||
# On wrong branch, note the commit hash
|
||||
Critical bug found in production:
|
||||
|
||||
```pwsh
|
||||
# You're on feature-new-ui branch
|
||||
# You just committed a critical security fix
|
||||
|
||||
git log --oneline
|
||||
# Switch to correct branch
|
||||
git switch correct-branch
|
||||
git cherry-pick <commit-hash>
|
||||
# Go back and remove from wrong branch
|
||||
git switch wrong-branch
|
||||
git reset --hard HEAD~1
|
||||
# Note the hash of your fix commit
|
||||
|
||||
# Switch to production branch
|
||||
git switch production
|
||||
|
||||
# Apply just that fix
|
||||
git cherry-pick <fix-commit-hash>
|
||||
|
||||
# Deploy to production
|
||||
# Your fix is live, but new UI stays in development
|
||||
```
|
||||
|
||||
### Backporting
|
||||
You need to apply a fix to an older release branch:
|
||||
```bash
|
||||
### Backporting to Old Versions
|
||||
|
||||
```pwsh
|
||||
# You fixed a bug on main
|
||||
git switch main
|
||||
git log --oneline
|
||||
# Note the fix commit hash
|
||||
|
||||
# Apply to older release branch
|
||||
git switch release-2.5
|
||||
git cherry-pick <fix-commit-hash>
|
||||
|
||||
# Apply to even older release
|
||||
git switch release-2.0
|
||||
git cherry-pick <fix-from-main>
|
||||
git cherry-pick <fix-commit-hash>
|
||||
|
||||
# Same fix now on three branches!
|
||||
```
|
||||
|
||||
## What You'll Learn
|
||||
## Troubleshooting
|
||||
|
||||
Cherry-pick is a surgical tool in your Git toolbox. While merge and rebase work with entire branches, cherry-pick lets you be selective about which changes to apply. This is invaluable for managing hotfixes, maintaining multiple release branches, and handling situations where you need specific changes without bringing along everything else. Understanding when to use cherry-pick versus other Git operations is a mark of Git expertise.
|
||||
### "I can't remember the commit hash!"
|
||||
|
||||
```pwsh
|
||||
# See commits on the source branch
|
||||
git log development --oneline
|
||||
|
||||
# Search for specific text in commit messages
|
||||
git log development --oneline --grep="security"
|
||||
|
||||
# See recent commits with more detail
|
||||
git log development --oneline -n 10
|
||||
```
|
||||
|
||||
### "I cherry-picked in the wrong order!"
|
||||
|
||||
Order matters! If commit B depends on commit A, cherry-pick A first:
|
||||
|
||||
```pwsh
|
||||
# Wrong order might cause issues
|
||||
git cherry-pick B # Might fail if it needs changes from A
|
||||
|
||||
# Correct order
|
||||
git cherry-pick A
|
||||
git cherry-pick B
|
||||
```
|
||||
|
||||
### "How do I see what will change before cherry-picking?"
|
||||
|
||||
```pwsh
|
||||
# See what changes are in a commit
|
||||
git show <commit-hash>
|
||||
|
||||
# Compare your current branch with a commit
|
||||
git diff HEAD <commit-hash>
|
||||
```
|
||||
|
||||
## Tips for Success
|
||||
|
||||
💡 **Copy the commit hashes** - Write them down before switching branches
|
||||
💡 **Cherry-pick oldest first** - Apply commits in chronological order
|
||||
💡 **Check your branch** - Always verify you're on the target branch first with `git branch`
|
||||
💡 **Verify after each pick** - Run `git log --oneline` to confirm it worked
|
||||
💡 **Use the graph** - `git log --oneline --graph --all` shows the full picture
|
||||
💡 **Original stays put** - Cherry-pick copies, doesn't move commits
|
||||
|
||||
## What You've Learned
|
||||
|
||||
After completing this module, you understand:
|
||||
|
||||
- ✅ Cherry-pick copies specific commits between branches
|
||||
- ✅ `git cherry-pick <hash>` applies a commit to current branch
|
||||
- ✅ Cherry-picked commits get new hashes but same changes
|
||||
- ✅ Use cherry-pick for selective deployment of changes
|
||||
- ✅ Cherry-pick is different from merge (selective vs all)
|
||||
- ✅ Original commit stays on source branch
|
||||
|
||||
## Next Steps
|
||||
|
||||
Ready to continue? Cherry-pick is a powerful tool for selective change management. Next modules will cover more advanced Git operations.
|
||||
|
||||
To start over:
|
||||
```pwsh
|
||||
.\reset.ps1
|
||||
```
|
||||
|
||||
**Need help?** Run `git status` to see what Git suggests, or `git log --oneline --graph --all` to see the full picture!
|
||||
|
||||
Reference in New Issue
Block a user