21 KiB
Module 03: Branching and Merging
About This Module
Welcome to Module 03! This module is different from the others - it uses a checkpoint system that lets you work through three related concepts in one continuous repository:
- Branching Basics - Create and work with feature branches
- Merging Branches - Combine branches together
- Resolving Merge Conflicts - Fix conflicts when Git can't merge automatically
Instead of three separate modules, you'll progress through checkpoints in a single Git repository, building on each previous section. You can jump between checkpoints, skip ahead, or restart any section at any time!
Why Checkpoints?
Branching, merging, and conflict resolution are naturally connected - you can't understand merging without branches, and you can't master conflicts without trying to merge. The checkpoint system lets you learn these concepts as a continuous workflow, just like real development.
Quick Start
Setup
Create the challenge environment:
.\setup.ps1
This creates a complete Git repository with all checkpoints ready.
Working with Checkpoints
View available checkpoints:
.\reset.ps1
Jump to a specific checkpoint:
.\reset.ps1 start # Checkpoint 1: Branching Basics
.\reset.ps1 merge # Checkpoint 2: Merging Branches
.\reset.ps1 merge-conflict # Checkpoint 3: Resolving Conflicts
Verify your progress:
.\verify.ps1 # Verify all checkpoints complete
.\verify.ps1 start # Verify Checkpoint 1 only
.\verify.ps1 merge # Verify Checkpoint 2 only
.\verify.ps1 merge-conflict # Verify Checkpoint 3 only
Recommended Workflow
Complete checkpoints in order:
- Start with Checkpoint 1 (Branching Basics)
- Progress to Checkpoint 2 (Merging)
- Finish with Checkpoint 3 (Merge Conflicts)
Or skip to any checkpoint if you already know the earlier concepts!
Checkpoint 1: Branching Basics
Learning Objectives
- Understand what a branch is in Git
- Create new branches with
git switch -c - Switch between branches with
git switch - View all branches with
git branch - Understand that branches are independent lines of development
Your Task
Create a feature branch called feature-login, add a login.py file, and make commits to demonstrate that branches allow independent development.
Steps:
- Navigate to the challenge directory:
cd challenge - Create a new branch:
git switch -c feature-login - Create a file:
login.py(with any content you like) - Commit your file:
git add login.py && git commit -m "Add login module" - Make another change to
login.pyand commit it - Switch back to main:
git switch main - Notice that
login.pydoesn't exist on main! - Switch back to your feature:
git switch feature-login - Notice that
login.pyexists again!
Verify: Run .\verify.ps1 start to check your solution.
What is a Branch?
A branch in Git is an independent line of development. Think of it as a parallel universe for your code - you can make changes without affecting the main timeline.
Visual representation:
main: A---B---C
\
feature-login: D---E
- Both branches share commits A and B
- Branch
maincontinues with commit C - Branch
feature-logingoes in a different direction with commits D and E - Changes in one branch don't affect the other!
Why Use Branches?
Branches let you:
- Experiment safely - Try new ideas without breaking main
- 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
Key Concepts
- Branch: A lightweight movable pointer to a commit
- HEAD: A pointer showing which branch you're currently on
- main: The default branch (formerly called "master")
- Feature branch: A branch created for a specific feature or task
Useful Commands
# View all branches (current branch marked with *)
git branch
# Create a new branch
git branch feature-login
# Switch to a branch
git switch feature-login
# Create AND switch in one command
git switch -c feature-login
# Switch back to previous branch
git switch -
# Delete a branch (only if merged)
git branch -d feature-login
# Force delete a branch
git branch -D feature-login
Understanding HEAD
HEAD is Git's way of saying "you are here." It points to your current branch.
When you run git switch main, HEAD moves to point to main.
When you run git switch feature-login, HEAD moves to point to feature-login.
Checkpoint 2: Merging Branches
Prerequisites: Complete Checkpoint 1 OR run .\reset.ps1 merge
Learning Objectives
- Understand what merging means in Git
- Merge a feature branch back into main
- Use
git mergeto combine branches - Understand merge commits
- Visualize merged branches with
git log --graph
Your Task
You've completed work on your feature-login branch. Now merge it back into main to include the login functionality in your main codebase.
Scenario:
- You created the
feature-loginbranch and added login functionality - Meanwhile, development continued on
main(README and app.py were added) - Now you need to merge your login feature into main
Steps:
- Make sure you're in the challenge directory:
cd challenge - Check which branch you're on:
git branch - Switch to main if needed:
git switch main - View the branch structure:
git log --oneline --graph --all - Merge feature-login into main:
git merge feature-login - View the result:
git log --oneline --graph --all
Verify: Run .\verify.ps1 merge to check your solution.
What is Merging?
Merging is the process of combining changes from one branch into another.
Think of it like combining two streams into one river - all the water (code) flows together.
Before Merging
You have two branches with different work:
main: A---B---C---D
\
feature-login: E---F
- Main branch progressed with commits C and D
- Feature-login branch has commits E and F
- They diverged at commit B
After Merging
You bring the feature branch into main:
main: A---B---C---D---M
\ /
feature-login: E-----F
- Commit M is a merge commit - it combines both branches
- Main now has all the work from both branches
- Your login feature is now part of main!
How to Merge
Merging is simple - just two steps:
1. Switch to the branch you want to merge INTO:
git switch main
This is the branch that will receive the changes.
2. Merge the other branch:
git merge feature-login
This brings changes from feature-login into main.
That's it! Git automatically combines the changes.
Understanding Merge Commits
When you merge, Git creates a special commit called a merge commit.
What makes it special?
- It has TWO parent commits (one from each branch)
- It represents the point where branches come back together
- The message typically says "Merge branch 'feature-login'"
See your merge commit:
git log --oneline
Look for the merge commit at the top - it will say something like:
abc1234 Merge branch 'feature-login'
Types of Merges
Three-way merge (what you just did):
- Both branches have new commits
- Git creates a merge commit
- History shows both branches clearly
Fast-forward merge:
- Main hasn't changed since the branch was created
- Git just moves the main pointer forward
- No merge commit needed!
# Before (fast-forward merge)
main: A---B
\
feature: C---D
# After (main just moves forward)
main: A---B---C---D
Visualizing Branches
The --graph flag is your best friend:
git log --oneline --graph --all
What the graph shows:
*= A commit|= A branch line/and\= Branches splitting/joining- Branch names in parentheses
Example output:
* a1b2c3d (HEAD -> main) Merge branch 'feature-login'
|\
| * e4f5g6h (feature-login) Add password validation
| * i7j8k9l Add login module
* | m1n2o3p Add README documentation
* | q4r5s6t Add app.py entry point
|/
* u7v8w9x Add main functionality
* y1z2a3b Initial commit
Useful Commands
# Merge a branch into your current branch
git merge <branch-name>
# Abort a merge if something goes wrong
git merge --abort
# View merge commits only
git log --merges
# View branch structure
git log --oneline --graph --all
# See which branches have been merged into main
git branch --merged main
# See which branches haven't been merged
git branch --no-merged main
Checkpoint 3: Resolving Merge Conflicts
Prerequisites: Complete Checkpoint 2 OR run .\reset.ps1 merge-conflict
Learning Objectives
- Understand what merge conflicts are and why they occur
- Identify merge conflicts in your repository
- Read and interpret conflict markers (
<<<<<<<,=======,>>>>>>>) - Resolve merge conflicts manually
- Complete a merge after resolving conflicts
Your Task
You have an update-config branch that modified config.json, and the main branch also modified config.json in a different way. When you try to merge, Git can't automatically combine them - you'll need to resolve the conflict manually.
Your mission:
- Attempt to merge the
update-configbranch intomain - Git will tell you there's a conflict - don't panic!
- Resolve the conflict by keeping BOTH settings (timeout AND debug)
- Complete the merge
Steps:
- Make sure you're in challenge directory:
cd challenge - Verify you're on main:
git branch - Try to merge:
git merge update-config - Git will report a conflict!
- Open
config.jsonin your text editor - Follow the resolution guide below
- Save the file
- Stage the resolved file:
git add config.json - Complete the merge:
git commit
Verify: Run .\verify.ps1 merge-conflict to check your solution.
What Are Merge Conflicts?
A merge conflict occurs when Git cannot automatically combine changes because both branches modified the same part of the same file.
Example scenario:
main branch: changes line 5 to: "timeout": 5000
update-config: changes line 5 to: "debug": true
Git doesn't know which one you want (or if you want both)! So it asks you to decide.
When do conflicts happen?
- ✅ Two branches modify the same lines in a file
- ✅ One branch deletes a file that another branch modifies
- ✅ Complex changes Git can't merge automatically
- ❌ Different files are changed (no conflict!)
- ❌ Different parts of the same file are changed (no conflict!)
Don't fear conflicts! They're a normal part of collaborative development. Git just needs your help to decide what the final code should look like.
Step-by-Step: Resolving Your First Conflict
Step 1: Attempt the Merge
cd challenge
git merge update-config
You'll see:
Auto-merging config.json
CONFLICT (content): Merge conflict in config.json
Automatic merge failed; fix conflicts and then commit the result.
Don't panic! This is normal. Git is just asking for your help.
Step 2: Check What Happened
git status
You'll see:
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: config.json
This tells you that config.json needs your attention!
Step 3: Open the Conflicted File
Open config.json in your text editor. You'll see special conflict markers:
{
"app": {
"name": "MyApp",
"version": "1.0.0",
"port": 3000,
<<<<<<< HEAD
"timeout": 5000
=======
"debug": true
>>>>>>> update-config
}
}
Step 4: Understand the Conflict Markers
<<<<<<< HEAD
"timeout": 5000 ← Your current branch (main)
=======
"debug": true ← The branch you're merging (update-config)
>>>>>>> update-config
What each marker means:
<<<<<<< HEAD- Start of your changes (current branch)=======- Separator between the two versions>>>>>>> update-config- End of their changes (branch being merged)
Step 5: Decide What to Keep
You have three options:
Option 1: Keep ONLY your changes (timeout)
"timeout": 5000
Option 2: Keep ONLY their changes (debug)
"debug": true
Option 3: Keep BOTH changes ← This is what we want!
"timeout": 5000,
"debug": true
For this challenge, choose Option 3 - keep both settings!
Step 6: Edit the File
Delete ALL the conflict markers and keep both settings:
Before (with conflict markers):
{
"app": {
"name": "MyApp",
"version": "1.0.0",
"port": 3000,
<<<<<<< HEAD
"timeout": 5000
=======
"debug": true
>>>>>>> update-config
}
}
After (resolved):
{
"app": {
"name": "MyApp",
"version": "1.0.0",
"port": 3000,
"timeout": 5000,
"debug": true
}
}
Important:
- Remove
<<<<<<< HEAD - Remove
======= - Remove
>>>>>>> update-config - Keep both the timeout and debug settings
- Ensure valid JSON syntax (notice the comma after timeout!)
Step 7: Save the File
Save config.json with your changes.
Step 8: Stage the Resolved File
Tell Git you've resolved the conflict:
git add config.json
Step 9: Check Status
git status
You'll see:
On branch main
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Perfect! Git confirms the conflict is resolved.
Step 10: Complete the Merge
Commit the merge:
git commit
Git will open an editor with a default merge message. You can accept it or customize it.
Done! Your merge is complete!
Common Mistakes to Avoid
❌ Forgetting to remove conflict markers
<<<<<<< HEAD ← Don't leave these in!
"timeout": 5000,
"debug": true
>>>>>>> update-config ← Don't leave these in!
This breaks your code! Always remove ALL markers.
❌ Committing without staging
git commit # Error! You didn't add the file
Always git add the resolved file first!
❌ Keeping only one side when both are needed If you delete one setting, you lose that work. For this challenge, you need BOTH!
❌ Breaking syntax
"timeout": 5000 ← Missing comma!
"debug": true
Always verify your file is valid after resolving!
Aborting a Merge
Changed your mind? You can abort the merge anytime:
git merge --abort
This returns your repository to the state before you started the merge. No harm done!
Useful Commands
# Attempt a merge
git merge <branch-name>
# Check which files have conflicts
git status
# Abort the merge and start over
git merge --abort
# After resolving conflicts:
git add <resolved-file>
git commit
# View conflicts in a different style
git diff --ours # Your changes
git diff --theirs # Their changes
git diff --base # Original version
Pro Tips
💡 Prevent conflicts
- Pull changes frequently:
git pull - Communicate with your team about who's working on what
- Keep branches short-lived and merge often
💡 Make conflicts easier
- Work on different files when possible
- If you must edit the same file, coordinate with teammates
- Make small, focused commits
💡 When stuck
- Read the conflict markers carefully
- Look at
git logto understand what each side changed - Ask a teammate to review your resolution
- Use a merge tool:
git mergetool
Complete Command Reference
Branching
git branch # List all branches
git branch feature-name # Create a new branch
git switch branch-name # Switch to a branch
git switch -c feature-name # Create and switch
git switch - # Switch to previous branch
git branch -d feature-name # Delete branch (if merged)
git branch -D feature-name # Force delete branch
Merging
git merge branch-name # Merge a branch into current branch
git merge --no-ff branch-name # Force a merge commit
git merge --abort # Abort a merge in progress
git log --merges # View only merge commits
Viewing History
git log --oneline --graph --all # Visual branch structure
git log --oneline # Compact commit list
git log --graph --decorate --all # Detailed branch view
git log main..feature-login # Commits in feature not in main
git diff main...feature-login # Changes between branches
Conflict Resolution
git status # See conflicted files
git diff # View conflicts
git add resolved-file # Mark file as resolved
git commit # Complete the merge
git merge --abort # Give up and start over
Checkpoint Commands (This Module)
.\reset.ps1 # Show available checkpoints
.\reset.ps1 start # Jump to Checkpoint 1
.\reset.ps1 merge # Jump to Checkpoint 2
.\reset.ps1 merge-conflict # Jump to Checkpoint 3
.\verify.ps1 # Verify all complete
.\verify.ps1 start # Verify Checkpoint 1
.\verify.ps1 merge # Verify Checkpoint 2
.\verify.ps1 merge-conflict # Verify Checkpoint 3
Troubleshooting
"I'm on the wrong branch!"
git switch main # Switch to main
git branch # Verify current branch
"I made commits on the wrong branch!"
Don't panic! You can move them:
# You're on main but should be on feature-login
git switch feature-login # Switch to correct branch
git merge main # Bring the commits over
git switch main
git reset --hard HEAD~1 # Remove from main (careful!)
Or use cherry-pick (covered in a later module).
"The merge created a mess!"
Abort and try again:
git merge --abort
git status # Verify you're back to clean state
"I want to start this checkpoint over!"
Use the reset script:
.\reset.ps1 start # Go back to Checkpoint 1
This resets your repository to the beginning of that checkpoint.
"I can't find my branch!"
List all branches:
git branch --all # Shows all branches including remote
The branch might have been deleted after merging (this is normal!).
"How do I know which checkpoint I'm on?"
.\reset.ps1 # Shows current checkpoint
git log --oneline --graph --all --decorate # Shows all tags/branches
Real-World Workflow Example
Here's how professional developers use these skills:
Day 1: Start a new feature
git switch main
git pull # Get latest changes
git switch -c feature-dark-mode # New feature branch
# ... make changes ...
git add .
git commit -m "Add dark mode toggle"
Day 2: Continue work
git switch feature-dark-mode # Resume work
# ... make more changes ...
git add .
git commit -m "Add dark mode styles"
Day 3: Ready to merge
git switch main
git pull # Get latest main
git switch feature-dark-mode
git merge main # Bring main's changes into feature
# Resolve any conflicts
git switch main
git merge feature-dark-mode # Merge feature into main
git push # Share with team
git branch -d feature-dark-mode # Clean up
This is exactly what you just practiced!
What You've Learned
By completing all three checkpoints, you now understand:
Checkpoint 1: Branching Basics
- ✅ Branches create independent lines of development
- ✅
git switch -ccreates and switches to a new branch - ✅ Changes in one branch don't affect others
- ✅ Branches are lightweight and easy to create
Checkpoint 2: Merging Branches
- ✅ Merging combines work from two branches
- ✅ Merge commits have two parent commits
- ✅
git mergebrings changes into your current branch - ✅ Three-way merges create a merge commit
Checkpoint 3: Resolving Merge Conflicts
- ✅ Conflicts happen when the same lines are changed differently
- ✅ Conflict markers show both versions
- ✅ You choose what the final code should look like
- ✅ Conflicts are normal and easy to resolve with practice
Next Steps
Completed the module? Great work! You're ready to move on.
Want more practice? Jump to any checkpoint and try again:
.\reset.ps1 start # Practice branching
.\reset.ps1 merge # Practice merging
.\reset.ps1 merge-conflict # Practice conflict resolution
Ready for the next module? Continue to Module 04 to learn about cherry-picking specific commits!
Need help? Review the relevant checkpoint section above, or run git status to see what Git suggests!