JAVA • GETTING STARTED AND TOOLING

Resolving Merge Conflicts — Resolve simple merge conflicts in text files (intro)

Learn how to identify and fix merge conflicts when Git cannot automatically combine changes from different branches.

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
Bell Labs developed the Source Code Control System, allowing one programmer at a time to "check out" a file and lock it so nobody else could edit it — a brute-force way to prevent conflicts.
1986
CVS Introduces Merging
The Concurrent Versions System allowed multiple developers to edit the same file at the same time and attempted automatic merging, but conflicts still required manual resolution.
2005
Git Is Created
Linus Torvalds built Git for Linux kernel development. Git's distributed model made branching and merging extremely fast, but merge conflicts remained an inevitable part of collaboration.
2008
GitHub Launches
GitHub brought Git to the masses with a web interface, making collaboration — and merge conflicts — a daily experience for millions of developers worldwide.

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.

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.

1

Branch

A separate line of development in a Git repository. Each branch can have its own commits that diverge from the main code. Creating a branch is like making a photocopy of a document to edit independently.
2

Merge

The process of combining changes from one branch into another. Git compares the files on both branches and automatically integrates non-overlapping edits into a single result.
3

Merge Conflict

Occurs when two branches modify the exact same lines of a file in different ways. Git cannot decide which version is correct, so it pauses the merge and asks you to choose.
4

Conflict Markers

Special lines that Git inserts into a conflicted file — <<<<<<< HEAD, =======, and >>>>>>> — to show you both versions of the conflicting code so you can decide what to keep.
5

Resolution

The act of editing the conflicted file to produce the final desired version, removing all conflict markers, staging the file with git add, and completing the merge with git commit.
✦ KEY TAKEAWAY
Think of a merge conflict like two people writing different endings to the same story chapter. The word processor can't pick a winner — it highlights both versions and asks the author to decide. In the same way, Git highlights both versions of conflicting code and hands you the decision. You're the author; Git is just the messenger.

Visual Explanation — How Conflicts Happen

This diagram shows two branches diverging from commit B. Commit D on main changes line 5 to 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.

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
public int getMaxScore() { <<<<<<< 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

  1. Keep your version: Delete the incoming code (between ======= and >>>>>>>) and all three marker lines, keeping only return 100;
  2. Accept the incoming version: Delete your code (between <<<<<<< and =======) and all three marker lines, keeping only return 150;
  3. 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);

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.

The four-step workflow for resolving a merge conflict: attempt the merge, open and edit the conflicted files to remove markers, stage the resolved files with git add, and finalize the merge with git commit.
💡 Useful Commands During Conflict Resolution
Run 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.

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 MergeYou are on the main branch and run git merge partner-branch. Git responds with: CONFLICT (content): Merge conflict in Greeting.java. The merge is paused.
2
Step 2 — Open the Conflicted FileYou open Greeting.java in your text editor and see the following content: public class Greeting { public String getMessage() { <<<<<<< HEAD return "Hello, World!"; ======= return "Hi there, everyone!"; >>>>>>> partner-branch } }
3
Step 3 — Choose the ResolutionAfter 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 FileRun git add Greeting.java to tell Git that you have resolved the conflict in this file. If you run git status now, the file will no longer appear as "both modified."
5
Step 5 — Complete the MergeRun git 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. Your main branch now contains the combined changes from both branches, with your chosen resolution for the conflicting line.

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 mistakes vs. best practices when resolving merge conflicts
Common MistakeWhy It's a ProblemBest Practice
Leaving conflict markers in the fileYour Java code won't compile — <<<<<<< is not valid Java syntaxAlways search the entire file for <<<<<<< before committing
Deleting both versionsYou lose the code from both branches, creating a blank sectionKeep at least one version or write a new combined version
Forgetting to run git addGit still thinks the conflict is unresolved, blocking the commitAlways stage resolved files with git add before committing
Not communicating with teammatesYou might discard your teammate's important changesDiscuss the conflict with your partner before choosing a resolution
Working on the same branchMore frequent conflicts and harder-to-trace issuesUse feature branches so each person has their own workspace
✦ KEY TAKEAWAY
The biggest source of merge conflict pain is not the conflict itself — it's panicking and making hasty edits. Treat conflict resolution like proofreading an essay: read both versions carefully, understand the intent behind each change, and then craft the best combined result. Taking an extra two minutes to think it through will save you from introducing bugs.

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.

Today's skills vs. advanced Git workflows
What You Learned TodayAdvanced Version
Resolving conflicts in a single text fileResolving conflicts across dozens of files in a large project
Editing conflict markers in a plain text editorUsing IDE merge tools (IntelliJ, VS Code) with side-by-side visual diffs
Merging two branchesRebasing, cherry-picking, and interactive rebasing for a cleaner commit history
Working with one partnerPull requests and code reviews with entire development teams on GitHub or GitLab
Manual conflict resolutionAutomated CI/CD pipelines that detect and flag conflicts before they reach the main branch

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.

Practice Problems

PROBLEM 1 — CONCEPTUAL
Explain in your own words why Git cannot automatically resolve a merge conflict. Under what specific conditions does a conflict occur?
PROBLEM 2 — BASIC CALCULATION
Given the following conflicted file content, write out the final resolved version if you decide to keep only the HEAD (current branch) version: public int getAge() { <<<<<<< HEAD return 17; ======= return 18; >>>>>>> birthday-update }
PROBLEM 3 — INTERMEDIATE
You attempt to merge and Git reports conflicts in two files: Main.java and Config.java. Describe the complete sequence of commands and actions you would take to resolve both conflicts and finish the merge.
PROBLEM 4 — APPLIED
You and your project partner are building a Java game. Your partner changed the player speed to 5 on their branch, while you changed it to 8 on yours. The conflicted file looks like this: private int playerSpeed; <<<<<<< HEAD playerSpeed = 8; ======= playerSpeed = 5; >>>>>>> partner-branch Neither value is wrong — your partner lowered it for mobile testing, and you raised it for desktop. Write a resolved version that works for both platforms.
PROBLEM 5 — CRITICAL THINKING
A classmate says, "Merge conflicts are always bad and mean someone made a mistake." Do you agree or disagree? Explain your reasoning, and describe at least one strategy teams can use to reduce (but not eliminate) the frequency of merge conflicts.

Lesson 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.

Varsity Tutors • Java • Resolving Merge Conflicts — Resolve simple merge conflicts in text files (intro)