# Module 05: Cherry-Pick ## Learning Objectives 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 - Understand common use cases for cherry-picking - Learn how cherry-pick creates new commits with different hashes ## Setup Create the challenge environment: ```pwsh .\setup.ps1 ``` 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 ``` **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`) **Inspect specific commits:** ```pwsh # See what files a commit changed git show # 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 # 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 ``` 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 # 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 # Cherry-pick multiple commits (in order) git cherry-pick # Cherry-pick a range of commits git cherry-pick .. # Abort a cherry-pick if something goes wrong git cherry-pick --abort ``` ### After Cherry-Pick ```pwsh # Verify the commit was added git log --oneline # See what files changed git show HEAD # Compare branches git log main..development --oneline ``` ## Common Workflows ### Hotfix to Production Critical bug found in production: ```pwsh # You're on feature-new-ui branch # You just committed a critical security fix git log --oneline # Note the hash of your fix commit # Switch to production branch git switch production # Apply just that fix git cherry-pick # Deploy to production # Your fix is live, but new UI stays in development ``` ### 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 # Apply to even older release git switch release-2.0 git cherry-pick # Same fix now on three branches! ``` ## Troubleshooting ### "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 # Compare your current branch with a commit git diff HEAD ``` ## 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 ` 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!