Git, CI/CD & GitOpsX · Merge ConflictsConflicts
Resolving with tools — git mergetool, VS Code, and merge tool configuration
What you'll learn
- Launch `git mergetool` during an in-progress merge and operate the tool until exit
- Configure the default merge tool with `git config merge.tool` and `git config mergetool.<tool>.path`
- Use VS Code as a merge tool by configuring `mergetool.vscode.cmd` to invoke its diff editor
- Distinguish tools that produce a fully-merged file (meld, kdiff3, VS Code) from tools that just show the conflict text (vimdiff)
- Recognise when a tool is overkill — single-hunk single-file conflicts are usually faster by hand
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
A merge tool is a UI that shows the conflict’s three inputs
(base, ours, theirs) and an editable result pane, and saves
the result back to Git when the engineer exits. git mergetool
runs the configured tool against every conflicted path, one at
a time, and waits for the tool to exit before moving on. The
tool is not required — small conflicts are faster by hand — but
for multi-file merges or multi-hunk files, a visual three-way
view saves substantial time.
Launching git mergetool
The command is run during an in-progress merge, after the conflict markers are written but before any resolution is staged:
git status
# Unmerged paths:
# both modified: terraform/iam/main.tf
git mergetool
# This message is displayed because Git is performing a merge.
#
# terraform/iam/main.tf
#
# Normal merge conflict for 'terraform/iam/main.tf':
# {local}: modified file
# {remote}: modified file
# Hit return to start merge resolution tool (vimdiff)):
The tool is launched against the file. When the tool exits,
git mergetool moves to the next conflicted file, or, if no
conflicts remain, prints a summary and returns to the shell.
The tool’s exit code matters: zero means the file is resolved
and automatically staged; non-zero means the engineer chose
to leave the file in conflict.
What a merge tool shows
Different tools render the three-way view differently, but the data is the same:
flowchart LR
A["Base\nstage 1"] --> D["Result pane\neditable"]
B["Ours\nstage 2"] --> D
C["Theirs\nstage 3"] --> D
D --> E["Save & exit\ngit add runs"]
Most tools render four panes (base, ours, theirs, result) in a 2x2 grid with colour-coded conflict highlights. vimdiff renders ours and theirs side by side with the merged file below. VS Code’s merge editor renders all four in a stacked layout with click-to-take buttons per hunk. The data is the same; the ergonomics differ.
Configuring the default tool
git mergetool reads the user’s merge.tool configuration
to decide which tool to launch. Git ships with built-in
profiles for common tools:
# Set the default merge tool
git config --global merge.tool vimdiff
# Set the default to meld (popular on Linux)
git config --global merge.tool meld
# Set the default to VS Code
git config --global merge.tool vscode
Git’s built-in profiles include araxis, bc, bc3,
codecompare, deltawalker, diffmerge, diffuse, ecmerge,
emerge, examdiff, guiffy, gvimdiff, kdiff3, meld,
opendiff, p4merge, smerge, tkdiff, tortoisemerge,
vimdiff, vscode, and winmerge. Each profile sets the
executable path, the command-line template, and the trust-
exit-code flag.
For tools not in the built-in list, supply a cmd template:
# Configure a custom tool not in the built-in list
git config --global merge.tool custom-merge
git config --global mergetool.custom-merge.cmd "my-merge-tool \$BASE \$LOCAL \$REMOTE \$MERGED"
git config --global mergetool.custom-merge.trustExitCode true
The four positional arguments ($BASE, $LOCAL, $REMOTE,
and $MERGED) are populated by git mergetool with the
absolute paths to the base, ours, theirs, and result files
respectively. The tool is launched with these paths in that
order, with the result file pre-populated with the conflict
markers; the tool edits the result, and git mergetool
reads it back when the tool exits.
VS Code as a merge tool
VS Code is not in Git’s oldest built-in list, but a working configuration is well-known. The two relevant settings:
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd "code --wait --merge \$REMOTE \$LOCAL \$BASE \$MERGED"
The code --wait --merge invocation opens VS Code’s merge
editor with the four inputs as read-only panes and the
result pane editable. VS Code’s merge editor offers click-
to-take buttons per hunk (“Accept Current Change”, “Accept
Incoming Change”, “Accept Both Changes”, “Accept Neither”),
which map to the four resolution shapes from X-03. Closing
the editor saves the result; git mergetool reads the file
back and stages it.
For an infrastructure team that already uses VS Code for day-to-day editing, VS Code as the merge tool is a low- friction choice: no new tool to learn, the editor is already in the workflow, and the merge editor is keyboard- navigable.
When to use a tool versus when to resolve by hand
The break-even point is small. The rule of thumb:
- One file, one hunk, fewer than 20 lines of conflict —
by hand. Opening
vimdiffor VS Code takes longer than reading 20 lines. - One file, multiple hunks, structural changes — mergetool layout is faster. The visual three-way layout makes per- hunk choices obvious.
- Multiple files, heterogeneous content —
git mergetoolwithgit diff --name-only --diff-filter=U | xargsmay parallelise, or one-at-a-time is fine. A multi-file merge of YAML, HCL, and Python at once benefits from the tool’s reminders that the engineer is on the second file and the third. - Binary conflicts — no tool helps. The binary file
resolution is
git checkout --oursor--theirs; the visual diff does not apply.
Production discipline
Three rules for configuring and using merge tools in a production workflow:
- Configure the default once per machine, not per merge.
A team-wide
~/.gitconfigblock that setsmerge.tool = vscode(or the team’s choice) ensures every team member sees the same tool when they rungit mergetool. Tool inconsistency is a friction cost that compounds across many merges. - Always review the file in the tool before exiting.
git mergetool’s auto-staging trusts the tool’s exit code; a tool that exits cleanly with markers still in the file will stage the markers. The review is the engineer’s check against this. - For binary conflicts, do not invoke a tool. Binary
files have no textual diff; the tool will show hex or
nothing useful. Use
git checkout --oursorgit checkout --theirsdirectly.
Cross-course references
- Linux for Production Sysadmins — Part XXVIII (ChangeMgmt) covers configuration management tool choices for manual conflict resolution; the tool-vs-hand trade-off is the same shape.
- Ansible for Production Sysadmins — Part XXXVII (RepoArch) discusses mergetool configurations for inventory files; YAML inventory is often easier in meld than in vimdiff.
- Terraform for Production Sysadmins — Part XIX (PR) recommends VS Code as the Terraform merge tool because of the HCL-aware merge editor extension.
Quiz
Knowledge check · 4 questions
Q1. Which configuration setting tells Git which merge tool `git mergetool` should launch?
Q2. When `git mergetool` exits with a clean exit code from the configured tool, it stages the file with `git add` automatically.
Q3. Name the four positional arguments `git mergetool` substitutes into a custom `mergetool.<tool>.cmd` template, and the variable that holds each input.
Q4. Configure a team's merge tools to handle heterogeneous IaC files (HCL, YAML, Python) and decide whether to centralise the configuration.
An infrastructure team of eight engineers works across Terraform (HCL), Ansible (YAML), and Python tooling. Each engineer currently uses a different merge tool: half use VS Code, two use vimdiff, one uses meld, one uses kdiff3. New joiners ask which tool to install. The team lead wants to standardise.
Passing score: 75%. Answers are checked in this browser.