Skip to main content

Resolving a merge conflict, without panicking

Summary: the merge conflict is the great nightmare of Git beginners. Yet it is a deliberate and benevolent mechanism: Git detects that it cannot decide on its own, and asks a human to arbitrate. This lesson explains why conflicts appear, how to read them, and gives the 5 steps to resolve them cleanly.


1. Why a conflict appears

Git automatically merges 95% of changes, as long as the modifications affect different areas of the code. A conflict appears only in one precise case: when two people modified the same line of the same file.

Crucial point: this is not a bug, it is a safety mechanism. Without Git, Alice's modification would silently overwrite Bob's (or vice versa). A reported conflict is a disaster avoided.


2. What a conflict looks like in a file

When Git detects a conflict, it modifies the file by inserting conflict markers that delimit the areas to arbitrate.

Here is what a conflicted file looks like:

server:
host: 0.0.0.0
port: 8080

<<<<<<< HEAD
timeout: 60
=======
timeout: 120
>>>>>>> feature/payment

database:
url: postgres://localhost/app

Decoding:

MarkerMeaning
<<<<<<< HEADStart of the current version (your target branch, often main)
=======Separator between the two versions
>>>>>>> feature/paymentEnd of the incoming version (the branch you are merging)

Between <<<<<<< HEAD and =======: what your current branch says. Between ======= and >>>>>>>: what the incoming branch says.

Your job: decide which version to keep, or merge the two by hand, then remove all the markers.


3. The 5 steps to resolve a conflict cleanly

Do not panic. Always follow the same sequence.

Step 1 · Read — identify the areas

git status (or your editor's Git tab) shows the list of conflicted files. Open them one by one.

A file may contain several conflict areas — each one is delimited by its own <<<<<<< / ======= / >>>>>>> triplet.

Step 2 · Understand — the why of each version

Before choosing, take 30 seconds to understand why the two versions exist.

  • Look at the name of the incoming branch (feature/payment, hotfix/security) — the context gives a clue.
  • Look at who made the original commit (git blame, or the author shown in the editor).
  • If doubt remains, go see the person concerned or ask on the team's Slack channel. No conflict deserves to be resolved blindly.

Step 3 · Arbitrate — four possible outcomes

For each conflict area, four outcomes are possible:

OutcomeWhen to choose it
Keep the current version (HEAD)The other branch's modification is obsolete or wrong
Keep the incoming versionYour version is obsolete or wrong
Combine the two by handBoth modifications are legitimate and complement each other
Write a third versionNeither of the two is right, a synthesis is needed

Most frequent case: combining the two. For example if Alice sets timeout: 60 and Bob sets timeout: 120, the real question to ask the team is "why must this timeout change?" — the answer dictates the right value, which may be neither 60 nor 120.

Step 4 · Clean up — remove the markers

No marker must remain in the final file. A search for <<<<<<< in your project must return zero results.

Tip: most modern editors (VS Code, JetBrains, Sublime) display conflicts with clickable buttons:

  • "Accept Current Change" (keep HEAD)
  • "Accept Incoming Change" (keep the incoming one)
  • "Accept Both Changes" (combine)
  • "Compare Changes" (visual diff)

These buttons remove the markers automatically after the choice.

Step 5 · Validate — test before committing

Before creating the merge commit, always run the tests. A badly resolved conflict may compile but break in production.

Once the tests are green, stage all the resolved files and create the commit. Git then generates a merge commit with a default message like Merge branch 'feature/payment' into main.


4. The three classic mistakes to avoid

Each of these three mistakes can be detected automatically:

  • Mistake 1: enforce a code review on every merge — a colleague will reread and spot it.
  • Mistake 2: configure your CI/CD to fail as soon as it detects <<<<<<< in a file.
  • Mistake 3: make the tests mandatory in the GitHub/GitLab branch protection rules.

5. How to avoid conflicts, upstream

A conflict is always resolvable, but the best conflict is the one that never happens. Four simple habits divide their frequency by 10.

These habits are the real Git skill — not mastery of commands, but the team discipline that prevents conflicts from appearing in the first place.


6. The special case of rebase

There is a second situation where you encounter conflicts: during a rebase. A rebase "replays" your commits on top of another base — useful for keeping a linear history, but each replayed commit can create an individual conflict.

Important difference:

  • A merge conflict: a single conflict to resolve, once for the whole merge.
  • A rebase conflict: potentially one conflict per replayed commit. It can quickly become painful.

Recommendation for a beginner: prefer merge over rebase until you feel comfortable. Rebase is a powerful tool, but one that takes months of practice to master. It is covered in depth in the Premium Git Course.


7. In case of absolute doubt — the emergency exit command

If you are completely lost in the middle of a conflict, there is always an emergency stop button: cancel the ongoing merge and return to the previous state.

Concretely, the command is git merge --abort (or git rebase --abort in case of a rebase). It is completely safe: it destroys no commit, it only cancels the ongoing operation.

Remember: in Git, almost everything is reversible. A badly negotiated conflict will never ruin your day if you know this command.


Remember in 30 seconds

  • A conflict appears only when two people modify the same line of the same file.
  • It is not a bug, it is a safety mechanism — without Git, the modification would have been silently overwritten.
  • Resolution follows 5 steps: read, understand, arbitrate, clean up, validate.
  • Never leave a <<<<<<< marker in a committed file.
  • Always re-run the tests after resolving a conflict.
  • In case of panic, the cancel command brings everything back to the previous state.

Next: Git in CI/CD and open source →