How to resolve merge conflicts

Merge conflicts happen when Git cannot automatically combine changes from two branches. This typically occurs when two developers edit the same lines in a file, or when one branch deletes a file that another branch modifies. Rather than guessing which version is correct, Git pauses the merge and asks you to resolve the conflict manually.

Understanding how to handle merge conflicts confidently is an essential Git skill. The process is straightforward once you know what to look for.

Identify Affected Files

When a merge conflict occurs, Git will tell you which files need attention. Navigate to your repository and run git status:

$ cd projects/learngit/shop
$ git status
> # On branch my-new-branch
> # You have unmerged paths.
> #   (fix conflicts and run "git commit")
> #
> # Unmerged paths:
> #   (use "git add ..." to mark resolution)
> #
> # both modified:      assets/style.css
> #
> no changes added to commit (use "git add" and/or "git commit -a")

Files listed under "Unmerged paths" contain conflicts that need resolving. You may see labels like both modified, deleted by us, or deleted by them depending on the type of conflict.

Understanding Conflict Markers

Git inserts conflict markers directly into the affected files. These markers show both versions of the conflicting code so you can decide what to keep:

body {
  background: #1a1a1a;
<<<<<<< HEAD
  color: #ffffff;
=======
  color: #000000;
>>>>>>> my-new-branch
  font: 400 18px/1.5 "PT Serif", sans-serif;
  margin: 0;
}

Here is what each marker means:

  • <<<<<<< HEAD marks the start of the changes from your current branch (the branch you are merging into)
  • ======= separates the two versions
  • >>>>>>> my-new-branch marks the end of the incoming changes from the branch being merged

Resolving Conflicts Step by Step

  1. Open the conflicted file in your text editor and search for <<<<<<< to find each conflict block.

  2. Review both versions. Use git diff to understand exactly what changed between the two branches before deciding which version to keep.

  3. Choose the correct code. You have three options:

    • Keep only the HEAD version (your current branch)
    • Keep only the incoming version (the branch being merged)
    • Combine both changes into a new version that incorporates the best of each
  4. Remove all conflict markers. Delete the <<<<<<<, =======, and >>>>>>> lines entirely. Only your resolved code should remain.

  5. Stage and commit the resolved file:

$ git add assets/style.css
$ git commit -m "Resolve merge conflict in style.css"

You can now merge the branches and push your changes to the remote repository.

Using a Merge Tool

For files with multiple conflicts or complex changes, a visual merge tool can save significant time. Git has built-in support for external merge tools:

$ git mergetool

This launches your configured merge tool for each conflicted file. Popular options include:

  • VS Code — built-in three-way merge editor that highlights conflicts inline and offers one-click resolution buttons. Set it as default with git config --global merge.tool vscode.
  • Beyond Compare — a dedicated diff and merge tool with strong support for directory-level comparisons.
  • kdiff3 — a free, cross-platform tool that shows a three-way diff (base, local, remote) side by side.

To configure your preferred tool globally:

$ git config --global merge.tool <tool-name>

Common Merge Conflict Scenarios

Same line edited differently — the most common case. Two branches change the same line in different ways. You need to manually decide which edit (or a combination) is correct.

File deleted in one branch, modified in another — Git cannot merge a deletion with an edit. You will see deleted by us or deleted by them in git status. Decide whether the file should be kept (with the edits) or removed.

Binary file conflicts — images, compiled assets, or other binary files cannot be merged line by line. Git will ask you to choose one version entirely. Use git checkout --theirs <file> or git checkout --ours <file> to pick a side.

Aborting a Merge

If a merge produces too many conflicts or you realise you are not ready to resolve them, you can abort and return to the state before the merge started:

$ git merge --abort

This resets your working directory and staging area to the pre-merge state. No changes are lost from either branch — you can attempt the merge again later. Consider using git stash to save any uncommitted work before retrying.

Preventing Merge Conflicts

While merge conflicts are unavoidable in collaborative projects, you can reduce their frequency:

  • Pull frequently. Run git fetch and merge or rebase regularly to stay up to date with the remote branch. The longer branches diverge, the more conflicts accumulate.
  • Keep pull requests small. Smaller, focused changesets are less likely to overlap with other developers' work and are easier to review.
  • Communicate with your team. If two people need to work on the same file, coordinate timing or split the work into separate sections.
  • Use feature branches. Isolate work on dedicated branches and merge back to the main branch often. See our guide on branching and merging for best practices.

For more complex conflict scenarios involving large codebases or unfamiliar code, see our guide on resolving merge conflicts with AI.

Ready to streamline your Git workflow? DeployHQ deploys your code automatically whenever you push to your repository.