refactor-reset-revert #1

Merged
floppydiscen merged 61 commits from refactor-reset-revert into main 2026-01-15 16:32:20 +00:00
Showing only changes of commit 3130874981 - Show all commits

View File

@@ -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!