Home / Alt manpages / git-mergetool(1)

  • git-mergetool(1)
  • User command
  • linux

Resolve Git Merge Conflicts Safely with git mergetool

You will use Git's merge-tool workflow to resolve selected conflict files, check the result, and leave the repository ready for the normal merge commit. Allow about 10 minutes for a small text conflict, plus whatever time you need to understand the competing changes. This guide covers the Git 2.43.0 manpage installed with the Debian git-man package. Later Git releases retain the workflow described here, but the available backends depend on what is installed on your machine.

Before you start

You need a Git repository paused during a merge, with at least one unmerged file, and a graphical or terminal merge tool installed. Do not run these commands in a repository with unrelated uncommitted work unless you have first saved it elsewhere. A merge tool writes to the working tree, and accepting the wrong side is a real content change.

Check the version and see which backends this installation recognises:

git --version
git mergetool --tool-help

On the reference system, the first command reports Git 2.43.0. The second prints the tools available to Git; it is not a guarantee that every listed program is installed or usable in the current display session.

Checkpoint

You have a paused merge and know the path of at least one file reported by git status as unmerged.

1. Inspect the conflict before opening a tool

Start with Git's status and, if the conflict is text-based, inspect the conflict markers. This gives you the surrounding context before a tool presents several versions of the file.

git status
git diff -- path/to/conflicted-file

Replace path/to/conflicted-file with a real path. With no path argument, git mergetool later visits every file that still has a merge conflict. Supplying a file or directory narrows the session; files without conflicts are skipped, and a directory includes unresolved files beneath it.

Do not treat git diff as the final answer. The working file can contain <<<<<<<<, ======= and >>>>>>> markers, but a merge tool also gives you the common ancestor and both branch versions. The goal is a coherent result, not merely removing the markers.

Checkpoint

You have identified the files that need a decision and have not changed them yet.

2. Choose an explicit merge tool

For a terminal session with Vim, run:

git mergetool --tool=vimdiff path/to/conflicted-file

Git's vimdiff layout shows LOCAL, BASE and REMOTE as reference buffers, with MERGED as the writable result. In this view, LOCAL is the version from the branch you had checked out, BASE is the common ancestor, and REMOTE is the version being merged in. Edit only the merged result, then save and quit Vim with :wq.

If you prefer another installed backend, substitute its name:

git mergetool --tool=meld path/to/conflicted-file

The installed manpage lists examples including emerge, gvimdiff, kdiff3, meld, vimdiff and tortoisemerge. Use git mergetool --tool-help for this machine's actual list. A named executable may still be missing, so Git cannot open it until you install it or point Git at the correct executable path.

To use the configured default instead, omit --tool:

git mergetool path/to/conflicted-file

Git first consults merge.tool. If it is unset, Git selects a suitable default. An explicit tool or configured tool normally disables the prompt between files; use --prompt when you want the opportunity to skip each path, or --no-prompt when you do not.

Checkpoint

The tool has opened the intended file, you can identify the writable merged view, and you have not accepted a side without checking the surrounding change.

3. Save the resolution and handle the backup

Finish the file in the merge tool and exit normally. With Vim, :wq records the merged buffer. If you started vimdiff and need to abandon that file without claiming success, use :cq. The latter exits with a failure status so Git does not silently treat an unfinished session as resolved.

By default, Git keeps the original conflict-marked file as path/to/conflicted-file.orig. This is a useful recovery copy while you check the result:

git status
git diff --check
git diff -- path/to/conflicted-file

git diff --check catches whitespace errors in the result. Read the diff as a human as well: automated checks cannot decide which behaviour the application needs. If the result is wrong, restore the conflict state from the .orig copy only after making sure it is the expected backup, then rerun the tool:

cp -- path/to/conflicted-file.orig path/to/conflicted-file
git mergetool --tool=vimdiff path/to/conflicted-file

The copy command changes the working file and can overwrite your current attempted resolution. Check the two paths first, and keep the backup until the new result is verified. When you are certain the merge is correct, the .orig file is safe to remove. You can instead configure Git to remove successful backups in a repository or user configuration:

git config mergetool.keepBackup false

This configuration change is ordinary user-level Git state, not an elevated operation. Leaving the default enabled is safer when you are learning a tool or resolving an important merge.

4. Mark the file resolved and verify the merge

Saving a file in the tool is not the same as staging it. Once the content passes your review, stage the resolved path:

git add -- path/to/conflicted-file
git status
git diff --cached --check

Repeat the mergetool and staging steps for every remaining conflict. A directory or a no-argument invocation can process several files, but reviewing and staging one logical group at a time makes an accidental acceptance easier to spot.

The status output should move the path from 'unmerged paths' to 'changes to be committed'. Before committing, run the project's relevant tests, formatter or build. Then finish the merge with the normal command:

git diff --cached
git commit

Do not use git commit merely to hide an unresolved conflict. If git status still lists unmerged paths, return to the previous checkpoint. If the whole merge should be abandoned, use the recovery command below before committing anything.

Useful configuration for custom tools

Git can run a known tool from a non-standard location:

git config --global mergetool.kdiff3.path /absolute/path/to/kdiff3

Only use a path that you have inspected and trust. A custom tool can also be defined with mergetool.<tool>.cmd. Git supplies shell variables named BASE, LOCAL, REMOTE and MERGED; the command must write the successful result to MERGED. For example, a wrapper script could be selected as mytool:

git config mergetool.mytool.cmd '/absolute/path/to/my-tool "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
git config mergetool.mytool.trustExitCode true
git mergetool --tool=mytool path/to/conflicted-file

Set trustExitCode to true only when the program reliably returns success or failure. Otherwise Git checks whether the merged file changed and may ask you to confirm the result. Treat custom commands as shell commands: quote the variables, use an absolute executable path when practical, and review the command before running it.

Abort or recover

If the merge itself is no longer wanted and you have not committed it, stop and check your repository state before undoing it. The usual Git recovery command is:

git status
git merge --abort

Warning

Aborting changes the working tree and attempts to return to the pre-merge state. Save unrelated work first, and do not assume it can recover edits made outside the merge. If you only need to retry one file, keep the .orig backup and rerun git mergetool instead.

Done means

  • git status shows no unmerged paths.
  • git diff --cached --check reports no whitespace errors.
  • The staged diff contains the intended resolution and no conflict markers.
  • The project's relevant tests or build complete successfully.
  • You have kept or deliberately removed each .orig backup.
  • The merge commit is made only after those checks pass.