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.
The route
Jump straight to the step you need, or tick off Done means at the end.
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 statusshows no unmerged paths.git diff --cached --checkreports 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
.origbackup. - The merge commit is made only after those checks pass.