Back to blog

How to Resolve Git Merge Conflicts: Step-by-Step CLI and VS Code Guide

Collaborating with multiple developers in a shared Git repository is highly productive, but it introduces one inevitable friction point: Merge Conflicts.

A merge conflict happens when Git cannot automatically reconcile differences between two commits. When this occurs, Git halts the merging process, marks the affected files, and leaves it up to you to manually decide which code changes to keep.

In this guide, we will analyze why merge conflicts happen, decode Git's file conflict markers, and walk through resolving them using both the command-line interface (CLI) and VS Code's visual editor.

Why Do Merge Conflicts Happen?

Git is highly intelligent. If developer A modifies a file at line 10, and developer B modifies the same file at line 80, Git will automatically merge their changes together without issue.

A conflict only arises when:

  1. Overlapping Edits: Two developers modify the exact same line (or adjacent lines) in a file on different branches, and attempt to merge them.
  2. File Deletion: One developer deletes a file, while another developer modifies that same file on a separate branch.

Because Git does not know which developer's work is correct, it suspends the merge and prompts you for resolution.

Decoding Git's Conflict Markers

When a conflict occurs, Git writes special markup indicators directly into the source file.

Open a conflicting file, and you will see blocks formatted like this:

<<<<<<< HEAD
const dbUrl = "mongodb://localhost:27017/prod";
=======
const dbUrl = "postgresql://localhost:5432/main";
>>>>>>> feature-db-migration

To resolve the conflict, you must understand these markers:

  • <<<<<<< HEAD: Marks the beginning of the conflicting lines. The code below this line represents your current active branch changes (e.g., main).
  • =======: The separator line. It isolates the code of the two branches.
  • >>>>>>> feature-db-migration: Marks the end of the conflict block, displaying the name of the branch you are attempting to pull in (the incoming changes).

Resolution Workflow: Step-by-Step

Step 1: Identify the Conflicting Files

If Git halts a merge, run git status to see which files are blocked:

git status

Under the "Unmerged paths" section, Git lists all conflicting files in red.

Step 2: Manually Resolve the Conflict

Open the conflicting files in your editor. You must:

  1. Analyze both blocks of code and decide what to keep. You can keep the HEAD code, the incoming branch code, combine elements of both, or rewrite the lines completely.
  2. Delete the conflict markers (<<<<<<<, =======, and >>>>>>>) from the file completely. Leaving these markers inside will result in syntax compilation errors.

Step 3: Stage the Resolved Files

Once a file is cleaned up and saved, tell Git the conflict has been resolved by staging it:

git add config.js

Verify your status again. The file should now appear green under "Changes to be committed".

Step 4: Finalize the Merge

With all conflicts staged, complete the merge operation:

git commit -m "Merge branch feature-db-migration and resolve conflicts"

If you are resolving conflicts during a rebase, use this command instead:

git rebase --continue

Resolving Conflicts Visually in VS Code

If you prefer a GUI, VS Code includes built-in Git conflict handlers.

When you open a conflicting file in VS Code, the editor highlights the blocks in blue and green, and provides clickable buttons directly above the markers:

  • Accept Current Change: Keeps your active branch code (HEAD) and deletes the incoming changes.
  • Accept Incoming Change: Overwrites your local code with the incoming branch changes.
  • Accept Both Changes: Keeps both blocks, placing one after the other.
  • Compare Changes: Opens a split-diff view to inspect line modifications side-by-side.

Clicking any of these options automatically applies the changes and deletes the Git markup syntax helper lines.

Conclusion

Merge conflicts are a normal part of team collaboration, not a sign of broken code. By understanding Git's conflict markers (HEAD vs incoming), using CLI commands like git status and git add to mark files resolved, or utilizing VS Code’s visual click selectors, you can safely resolve conflicts and merge code without data loss.