# Module 03: Branching and Merging ## Learning Objectives By the end of this module, you will: - Understand what branches are and why they're useful - Create and switch between branches - Make commits on different branches - Merge branches together - Visualize branch history with `git log --graph` - Understand merge commits and how they work ## Setup Create the challenge environment: ```bash .\setup.ps1 ``` This creates a repository with a realistic project history showing multiple merged feature branches. ## Overview **Branching** lets you create independent lines of development. Think of it like parallel universes for your code - you can experiment on one branch without affecting others. **Merging** combines work from different branches back together. ### Why Use Branches? - **Experiment safely** - Try new ideas without breaking main code - **Work in parallel** - Multiple features can be developed simultaneously - **Organize work** - Each feature/fix gets its own branch - **Collaborate better** - Team members work on separate branches ## Your Task ### Part 1: Explore the Repository First, explore the existing history to see what merging looks like: ```bash cd challenge git log --oneline --graph --all ``` You'll see a visual graph showing: - The `main` branch timeline - Feature branches that split off from main - Merge points where branches come back together **Study the graph:** - Look for the `*` symbols (commits) - Notice the `|`, `/`, and `\` characters (branch lines) - Find the merge commits (they have two parent lines converging) **Explore the branches:** ```bash # See all branches git branch --all # Check which files exist on different branches git ls-tree --name-only feature-login git ls-tree --name-only feature-api git ls-tree --name-only main ``` **View specific merges:** ```bash # See all merge commits git log --merges --oneline # See details of a specific merge git show ``` ### Part 2: Create Your Own Branch Now practice creating your own branch: ```bash # Create and switch to a new branch git switch -c my-feature # Verify you're on the new branch git branch ``` The `*` shows which branch you're currently on. ### Part 3: Make Commits on Your Branch Add some changes to your branch: ```bash # Create a new file or modify an existing one echo "# My Feature" > my-feature.md # Stage and commit git add . git commit -m "Add my feature" # Make another commit echo "More details" >> my-feature.md git add . git commit -m "Expand feature documentation" ``` **Important:** Changes on your branch don't affect main! ```bash # Switch to main git switch main # Notice your my-feature.md doesn't exist here ls # Switch back to your branch git switch my-feature # Now it exists again! ls ``` ### Part 4: Merge Your Branch Bring your work into main: ```bash # Switch to the branch you want to merge INTO git switch main # Merge your feature branch git merge my-feature # View the result git log --oneline --graph --all ``` You should see your feature branch merged into main! ### Part 5: Practice More Create additional branches to practice: ```bash # Create another feature git switch -c another-feature # Add changes and commits # ... your work ... # Merge it git switch main git merge another-feature ``` **Verify your work:** ```bash # From the module directory (not inside challenge/) .\verify.ps1 ``` ## Understanding Branches ### What is a Branch? A **branch** is a lightweight movable pointer to a commit. When you create a branch, Git creates a new pointer - it doesn't copy all your files! ``` main: A---B---C \ my-feature: D---E ``` - Both branches share commits A and B - Main has commit C - My-feature has commits D and E - They're independent! ### What is HEAD? `HEAD` points to your current branch. It's Git's way of saying "you are here." ```bash # HEAD points to main git switch main # Now HEAD points to my-feature git switch my-feature ``` ## Understanding Merging ### Types of Merges **Three-way merge** (most common): ``` Before: main: A---B---C \ feature: D---E After merge: main: A---B---C---M \ / feature: D---E ``` Git creates a merge commit `M` that has two parents (C and E). **Fast-forward merge**: ``` Before: main: A---B \ feature: C---D After merge: main: A---B---C---D ``` If main hasn't changed, Git just moves the pointer forward. No merge commit needed! ## Key Commands ### Branching ```bash # List all branches (* shows current branch) git branch # Create a new branch git branch feature-name # Create AND switch to new branch git switch -c feature-name # Switch to existing branch git switch branch-name # Switch to previous branch git switch - # Delete a branch (only if merged) git branch -d feature-name # Force delete a branch git branch -D feature-name ``` ### Merging ```bash # Merge a branch into your current branch git merge branch-name # Abort a merge if something goes wrong git merge --abort # Force a merge commit (even if fast-forward possible) git merge --no-ff branch-name ``` ### Viewing History ```bash # Visual branch graph git log --oneline --graph --all # Compact history git log --oneline # Only merge commits git log --merges # Show which branches have been merged into main git branch --merged main # Show which branches haven't been merged git branch --no-merged main ``` ## Common Workflows ### Creating a Feature ```bash # Start from main git switch main # Create feature branch git switch -c feature-awesome # Make changes echo "cool stuff" > feature.txt git add . git commit -m "Add awesome feature" # More changes... echo "more cool stuff" >> feature.txt git add . git commit -m "Improve awesome feature" ``` ### Merging a Feature ```bash # Switch to main git switch main # Merge your feature git merge feature-awesome # Delete the feature branch (optional) git branch -d feature-awesome ``` ### Keeping Main Updated While Working ```bash # You're on feature-awesome git switch feature-awesome # Main branch has new commits from others # Bring those into your feature branch git switch main git pull git switch feature-awesome git merge main # Or in one command (more advanced): git pull origin main ``` ## Troubleshooting ### "I'm on the wrong branch!" ```bash # Switch to the correct branch git switch correct-branch # Check current branch anytime git branch ``` ### "I made commits on the wrong branch!" Don't panic! You can move commits to another branch: ```bash # Create the correct branch from current state git branch correct-branch # Switch to wrong branch and remove the commits git switch wrong-branch git reset --hard HEAD~2 # Remove last 2 commits (adjust number) # Switch to correct branch - commits are there! git switch correct-branch ``` ### "The merge created unexpected results!" ```bash # Undo the merge git merge --abort # Or if already committed: git reset --hard HEAD~1 ``` ### "I want to see what changed in a merge!" ```bash # Show the merge commit git show # Compare two branches before merging git diff main..feature-branch ``` ## Tips for Success 💡 **Branch often** - Branches are cheap! Create one for each feature or experiment. 💡 **Commit before switching** - Always commit (or stash) changes before switching branches. 💡 **Keep branches focused** - One feature per branch makes merging easier. 💡 **Delete merged branches** - Clean up with `git branch -d branch-name` after merging. 💡 **Use descriptive names** - `feature-login` is better than `stuff` or `branch1`. 💡 **Visualize often** - Run `git log --oneline --graph --all` to understand your history. ## What You've Learned After completing this module, you understand: - ✅ Branches create independent lines of development - ✅ `git switch -c` creates a new branch - ✅ Changes in one branch don't affect others - ✅ `git merge` combines branches - ✅ Merge commits have two parent commits - ✅ `git log --graph` visualizes branch history - ✅ Branches are pointers, not copies of files ## Next Steps Ready to continue? The next module covers **merge conflicts** - what happens when Git can't automatically merge changes. To start over: ```bash .\reset.ps1 .\setup.ps1 ``` **Need help?** Review the commands above, or run `git status` to see what Git suggests!