SECTION 1
Historical Context & Motivation
Before version control systems existed, programmers working on the same project would email files back and forth, often overwriting each other's work by accident. Imagine two students editing the same Google Doc at the same time, both changing the same sentence — someone's edit is going to get lost. Early software teams faced this exact nightmare, and it motivated the invention of tools that could track and merge changes automatically.
As version control matured, systems like Git introduced powerful branching and merging capabilities. Most of the time, Git is smart enough to combine changes from two branches automatically. But when two developers edit the exact same lines in a file, Git cannot decide which version to keep. This is called a merge conflict, and resolving it is a fundamental skill every developer must learn.
1972 • SCCS — First Version Control
1986 • CVS Introduces Merging
2005 • Git Is Created
2008 • GitHub Launches
The core question this lesson addresses is: when Git tells you there is a merge conflict, what exactly happened, and how do you fix it? Understanding the anatomy of a conflict and the steps to resolve it will save you hours of frustration as you work on team projects — or even when you merge your own branches.
SECTION 2
Core Principles & Definitions
Before diving into hands-on conflict resolution, you need to understand a few key ideas. A branch in Git is an independent line of development — think of it as a separate copy of your project where you can make changes without affecting the main codebase. When you merge one branch into another, Git tries to combine the changes from both branches into a single unified version.
Branch
Merge
Merge Conflict
Conflict Markers
Resolution
KEY TAKEAWAY
SECTION 3
Visual Explanation — How Conflicts Happen
x = 20, while commit C on the feature branch changes the same line to x = 10. When you try to merge, Git cannot decide which value is correct, triggering a merge conflict.The diagram above illustrates the most common scenario that causes a merge conflict. Both branches started from the same base commit (B), but then each branch independently modified the exact same line in the same file. Git is excellent at combining changes that happen in different parts of a file — for example, if one branch edits line 5 and the other edits line 20, Git merges them without issue. The conflict only arises when changes overlap.
SECTION 4
How Merge Conflicts Work — The Conflict Markers
When Git encounters a merge conflict, it modifies the conflicting file by inserting conflict markers — three special lines that divide the two competing versions of the code. Understanding these markers is the key to resolving any conflict. Let's examine what a conflicted Java file actually looks like.
Anatomy of a Conflicted File
Suppose you have a file called Calculator.java and both branches modified the same method. After a failed merge, the file would contain something like this:
Conflicted File Example
<<<<<<< HEAD
return 100;
=======
return 150;
>>>>>>> feature-branch
}The three conflict markers each serve a specific purpose. The <<<<<<< HEAD line marks the beginning of your current branch's version (the branch you are merging into, often main). The ======= line is the divider between the two versions. The >>>>>>> feature-branch line marks the end of the incoming branch's version. Everything between <<<<<<< HEAD and ======= is what your current branch has, and everything between ======= and >>>>>>> feature-branch is what the incoming branch has.
Three Ways to Resolve
- Keep your version: Delete the incoming code (between ======= and >>>>>>>) and all three marker lines, keeping only
return 100; - Accept the incoming version: Delete your code (between <<<<<<< and =======) and all three marker lines, keeping only
return 150; - Write a combined version: Delete all three marker lines and write entirely new code that incorporates ideas from both versions — for example,
return Math.max(100, 150);
SECTION 5
The Complete Conflict Resolution Workflow
Knowing what conflict markers look like is only half the battle. You also need to know the Git commands that surround the resolution process. Here is the end-to-end workflow you will follow every time you encounter a merge conflict.
git add, and finalize the merge with git commit.Useful Commands During Conflict Resolution
git status at any point to see which files have conflicts (they appear as "both modified"). You can also run git diff to see the specific changes. If you want to abort the entire merge and go back to the state before you started, use git merge --abort.SECTION 6
Worked Example — Resolving a Java Conflict
Let's walk through a complete, realistic example. You are working on a Java project with a classmate. You are both editing a file called Greeting.java. Your classmate's branch changed the greeting message, and so did yours. Now you need to merge.
Resolving a Conflict in Greeting.java
- 1
Step 1 — Attempt the Merge
You are on themainbranch and rungit merge partner-branch. Git responds with:CONFLICT (content): Merge conflict in Greeting.java. The merge is paused. - 2
Step 2 — Open the Conflicted File
You openGreeting.javain your text editor and see the following content: public class Greeting { public String getMessage() {<<<<<<< HEADreturn "Hello, World!";=======return "Hi there, everyone!";>>>>>>> partner-branch} } - 3
Step 3 — Choose the Resolution
After talking with your partner, you decide to combine both ideas into a friendlier message. You delete all three conflict marker lines and replace the conflicting section with a single return statement.The resolved file now reads: public class Greeting { public String getMessage() { return "Hello there, everyone!"; } } Notice: no conflict markers remain in the file. - 4
Step 4 — Stage the File
Rungit add Greeting.javato tell Git that you have resolved the conflict in this file. If you rungit statusnow, the file will no longer appear as "both modified." - 5
Step 5 — Complete the Merge
Rungit commit. Git will open your default text editor with a pre-filled merge commit message. Save and close the editor to finalize the merge.The merge is complete. Yourmainbranch now contains the combined changes from both branches, with your chosen resolution for the conflicting line.
SECTION 7
Common Mistakes & Best Practices
Merge conflicts can feel intimidating at first, but most problems come from a small set of common mistakes. The table below contrasts bad habits with best practices so you can avoid the most frequent pitfalls.
| Common Mistake | Why It's a Problem | Best Practice |
|---|---|---|
| Leaving conflict markers in the file | Your Java code won't compile — <<<<<<< is not valid Java syntax | Always search the entire file for <<<<<<< before committing |
| Deleting both versions | You lose the code from both branches, creating a blank section | Keep at least one version or write a new combined version |
| Forgetting to run git add | Git still thinks the conflict is unresolved, blocking the commit | Always stage resolved files with git add before committing |
| Not communicating with teammates | You might discard your teammate's important changes | Discuss the conflict with your partner before choosing a resolution |
| Working on the same branch | More frequent conflicts and harder-to-trace issues | Use feature branches so each person has their own workspace |
Common mistakes vs. best practices when resolving merge conflicts
KEY TAKEAWAY
SECTION 8
Connection to Advanced Workflows
The simple text-file conflict resolution you learned today is the foundation for more advanced Git workflows used in professional software development. As your projects grow, you will encounter more complex scenarios. The table below gives you a preview of where this concept leads.
| What You Learned Today | Advanced Version |
|---|---|
| Resolving conflicts in a single text file | Resolving conflicts across dozens of files in a large project |
| Editing conflict markers in a plain text editor | Using IDE merge tools (IntelliJ, VS Code) with side-by-side visual diffs |
| Merging two branches | Rebasing, cherry-picking, and interactive rebasing for a cleaner commit history |
| Working with one partner | Pull requests and code reviews with entire development teams on GitHub or GitLab |
| Manual conflict resolution | Automated CI/CD pipelines that detect and flag conflicts before they reach the main branch |
Today's skills vs. advanced Git workflows
Don't worry about mastering all of these right now. The important thing is that the core skill — reading conflict markers, understanding both versions, editing the file, staging, and committing — remains exactly the same no matter how advanced the workflow becomes. Modern IDE tools simply add a graphical interface on top of the same process you practiced today.
SECTION 9
Practice Problems
Question 1: CONCEPTUAL
Show answer
Question 2: BASIC CALCULATION
Show answer
git add followed by git commit to complete the merge.Question 3: INTERMEDIATE
Main.java and Config.java. Describe the complete sequence of commands and actions you would take to resolve both conflicts and finish the merge.Show answer
git status to confirm which files are listed as 'both modified.' Then open Main.java in your editor, locate the conflict markers (<<<<<<< HEAD, =======, >>>>>>>), decide which version to keep or write a combined version, and remove all marker lines. Repeat this process for Config.java. After editing both files, run git add Main.java Config.java to stage both resolved files. Finally, run git commit to finalize the merge. You must resolve every conflicted file before Git allows the commit to proceed.Question 4: APPLIED
Show answer
Question 5: CRITICAL THINKING
Show answer
git pull to stay up-to-date, and (4) communicating about who is working on which files. Even with all these strategies, some conflicts are unavoidable — and that's perfectly okay, because you now know how to resolve them.SUMMARY
Lesson Summary
Summary
A merge conflict occurs when two branches modify the same lines of a file and Git cannot automatically determine which version to keep. Git inserts three conflict markers — <<<<<<< HEAD, =======, and >>>>>>> branch-name — into the file to show both versions of the conflicting code. Your job is to edit the file, choose the correct code (or combine both), and remove all marker lines.
The complete resolution workflow is: attempt the merge with git merge, open and edit each conflicted file, stage the resolved files with git add, and finalize with git commit. Remember that conflicts are a normal part of collaboration — not a mistake. Communicate with your teammates, read both versions carefully, and craft a resolution that preserves everyone's intent.