# Module 05: Merge Conflicts ## Learning Objectives By the end of this module, you will: - Understand what merge conflicts are and why they occur - Identify merge conflicts in your repository - Read and interpret conflict markers - Resolve merge conflicts manually step-by-step - Complete a merge after resolving conflicts ## Challenge ### Setup Run the setup script to create your challenge environment: ```powershell .\setup.ps1 ``` This will create a `challenge/` directory with a repository that has a merge conflict waiting to happen! ### Your Task You have a repository with a main branch and a feature branch called `update-config`. Both branches have modified the same configuration file in different ways, creating a merge conflict. **Your mission:** 1. Attempt to merge the `update-config` branch into `main` 2. Git will tell you there's a conflict - don't panic! 3. Resolve the conflict by keeping BOTH settings (timeout AND debug) 4. Complete the merge **Steps to follow:** 1. Navigate to the challenge directory: `cd challenge` 2. Make sure you're on main: `git branch` 3. Try to merge: `git merge update-config` 4. Git will report a conflict! 5. Open `config.py` in your text editor 6. Follow the step-by-step guide below to resolve it 7. Save the file, stage it, and commit ## What Are Merge Conflicts? A **merge conflict** occurs when Git cannot automatically combine changes because both branches modified the same lines in the same file. **Example scenario:** ``` main branch changes line 5: TIMEOUT = 30 feature branch changes line 5: DEBUG = True ``` Git doesn't know which one you want! So it asks you to decide. **When do conflicts happen?** - ✅ Two branches modify the same line(s) - ✅ One branch deletes a file that another branch modifies - ❌ Different files are changed (no conflict!) - ❌ Different lines in the same file are changed (no conflict!) ## Step-by-Step: Resolving Your First Conflict ### Step 1: Attempt the Merge ```bash cd challenge git merge update-config ``` **You'll see:** ``` Auto-merging config.py CONFLICT (content): Merge conflict in config.py 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 ```bash 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 ..." to mark resolution) both modified: config.py ``` This tells you that `config.py` needs your attention! --- ### Step 3: Open the Conflicted File Open `config.py` in your text editor. You'll see something like this: ```python # config.py - Application configuration APP_NAME = "My Application" VERSION = "1.0.0" <<<<<<< HEAD TIMEOUT = 30 ======= DEBUG = True >>>>>>> update-config ``` **Let's break down what you're seeing:** --- ## Understanding Conflict Markers Git has added special markers to show you both versions: ```python <<<<<<< HEAD ← Start of YOUR version (current branch) TIMEOUT = 30 ← What YOU have on main ======= ← Divider between versions DEBUG = True ← What THEY have on update-config >>>>>>> update-config ← End of THEIR version ``` **The three parts:** 1. **`<<<<<<< HEAD`** - Everything between here and `=======` is YOUR current branch's version 2. **`=======`** - This separates the two versions 3. **`>>>>>>> update-config`** - Everything between `=======` and here is the INCOMING branch's version --- ## Step 4: Decide What to Keep You have three options: **Option A: Keep YOUR version (main)** ```python # config.py - Application configuration APP_NAME = "My Application" VERSION = "1.0.0" TIMEOUT = 30 ``` **Option B: Keep THEIR version (update-config)** ```python # config.py - Application configuration APP_NAME = "My Application" VERSION = "1.0.0" DEBUG = True ``` **Option C: Keep BOTH (this is what we want!)** ```python # config.py - Application configuration APP_NAME = "My Application" VERSION = "1.0.0" TIMEOUT = 30 DEBUG = True ``` --- ## Step 5: Edit the File to Resolve the Conflict **What the file looks like NOW (with conflict markers):** ```python # config.py - Application configuration APP_NAME = "My Application" VERSION = "1.0.0" <<<<<<< HEAD TIMEOUT = 30 ======= DEBUG = True >>>>>>> update-config ``` **What you need to do:** 1. **Delete** the line `<<<<<<< HEAD` 2. **Keep** the line `TIMEOUT = 30` 3. **Delete** the line `=======` 4. **Keep** the line `DEBUG = True` 5. **Delete** the line `>>>>>>> update-config` **What the file should look like AFTER (conflict resolved):** ```python # config.py - Application configuration APP_NAME = "My Application" VERSION = "1.0.0" TIMEOUT = 30 DEBUG = True ``` **Save the file!** --- ## Step 6: Mark the Conflict as Resolved Tell Git you've fixed the conflict by staging the file: ```bash git add config.py ``` This tells Git: "I've resolved the conflict in this file, it's ready to be committed." --- ## Step 7: Check Your Status ```bash git status ``` **You should see:** ``` On branch main All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: config.py ``` Great! Git knows the conflict is resolved and is ready for you to complete the merge. --- ## Step 8: Complete the Merge ```bash git commit ``` Git will open your editor with a default merge message: ``` Merge branch 'update-config' # Conflicts: # config.py ``` You can keep this message or customize it. Save and close the editor. **Or use a one-liner:** ```bash git commit -m "Merge update-config: resolve config conflict" ``` --- ## Step 9: Verify the Merge ```bash git log --oneline --graph ``` You should see your merge commit! ```bash cat config.py ``` Verify the file has BOTH settings and NO conflict markers! --- ## Visual Summary: Before and After ### Before Resolution (WRONG ❌) ```python # config.py APP_NAME = "My Application" VERSION = "1.0.0" <<<<<<< HEAD TIMEOUT = 30 ======= DEBUG = True >>>>>>> update-config ``` **This will NOT run! Conflict markers are syntax errors!** ### After Resolution (CORRECT ✅) ```python # config.py APP_NAME = "My Application" VERSION = "1.0.0" TIMEOUT = 30 DEBUG = True ``` **Clean code, no markers, both settings preserved!** --- ## Common Mistakes to Avoid ### ❌ Mistake 1: Forgetting to Remove Conflict Markers ```python TIMEOUT = 30 ======= ← Still has conflict marker! DEBUG = True ``` **This is invalid Python code and will crash!** ### ❌ Mistake 2: Committing Without Staging ```bash # Wrong order: git commit # Error! File not staged # Correct order: git add config.py # Stage first git commit # Then commit ``` ### ❌ Mistake 3: Only Keeping One Side When You Need Both ```python # If the task asks for BOTH settings, this is wrong: TIMEOUT = 30 # Missing DEBUG = True ``` --- ## Useful Commands Reference ```bash # During a conflict git status # See which files have conflicts git diff # See the conflict in detail # Resolving git add # Mark file as resolved git commit # Complete the merge # If you want to start over git merge --abort # Cancel the merge, go back to before # After resolving git log --oneline --graph # See the merge commit ``` --- ## Real-World Conflict Resolution Workflow **Here's what you'll do every time you have a conflict:** ```bash # 1. Attempt the merge git merge feature-branch # → Git says: "CONFLICT! Fix it!" # 2. Check what's wrong git status # → Shows which files have conflicts # 3. Open the file, find the markers # <<<<<<< HEAD # your version # ======= # their version # >>>>>>> branch # 4. Edit the file to resolve # Remove the markers, keep what you need # 5. Stage the resolved file git add config.py # 6. Complete the merge git commit -m "Resolve conflict in config.py" # 7. Celebrate! 🎉 ``` --- ## What If You Get Stuck? ### Option 1: Abort the Merge ```bash git merge --abort ``` This puts everything back to how it was before the merge. You can try again! ### Option 2: Ask for Help ```bash git status # See what's going on git diff # See the conflict details ``` --- ## Pro Tips ✅ **Use `git status` constantly** - It tells you exactly what to do next ✅ **Search for `<<<<<<<`** - Your editor's search function can find all conflicts quickly ✅ **Test after resolving** - Make sure your code still works! ✅ **Read both sides carefully** - Sometimes you need parts from each version ✅ **Take your time** - Conflicts are not a race. Understand what changed and why. --- ## Verification Once you've resolved the conflict and completed the merge, verify your solution: ```powershell .\verify.ps1 ``` The verification will check that: - ✅ The merge conflict was resolved - ✅ The merge was completed successfully - ✅ BOTH settings are in the config file (TIMEOUT and DEBUG) - ✅ NO conflict markers remain - ✅ The merge commit exists in history --- ## Need to Start Over? If you want to reset the challenge and start fresh: ```powershell .\reset.ps1 ``` --- ## What You've Learned 🎉 **Congratulations!** You can now: - Recognize when a merge conflict occurs - Read and understand conflict markers - Edit files to resolve conflicts - Stage resolved files with `git add` - Complete a merge with `git commit` **This is a critical skill!** Every developer encounters merge conflicts. Now you know exactly what to do when they happen. --- ## Quick Reference Card **When you see a conflict:** 1. **Don't panic** ✅ 2. **Run `git status`** to see which files 3. **Open the file** in your editor 4. **Find the markers** (`<<<<<<<`, `=======`, `>>>>>>>`) 5. **Decide what to keep** (one side, other side, or both) 6. **Remove ALL markers** (the `<<<<<<<`, `=======`, `>>>>>>>` lines) 7. **Save the file** 8. **Stage it** (`git add filename`) 9. **Commit** (`git commit`) 10. **Verify** (`git status`, `git log --oneline --graph`) **Remember:** The conflict markers are NOT valid code - they MUST be removed!