Git Diff and Merge Workflows
Git performs diffs, merges, and rebases using its own internal algorithms. These operations are deterministic and fully automated: Git never relies on external tools.
However, there are situations where human judgment is required. For example, when changes need to be evaluated visually or semantically rather than textually. In those cases, Git can invoke external tools to assist with inspection, not decision-making.
A common example on macOS is FileMerge.app, which is installed with the Xcode Command Line Tools and can be launched by Git as a diff or merge helper.
Merge
When Git merges branches and can’t reconcile changes, it writes conflict markers into every conflicted file then stops the merge and notifies the user. For each file with conflict markers three stages are recorded in the Git index: common ours, and theirs. At this point the repository is in a conflicted merge state and Git waits for all conflicts to be resolved.
Given a conflicted file File.swift the files
generated
To fix the conflict manually edit the file:
- Open the file in an editor and remove the conflict markers.
- Stage the resolved file with
git add.
To fix the conflict in an external tool run:
git mergetoolgit mergetool launches the tool once for each conflicted
file, passing the BASE, ours, theirs, and merge result paths to the
tool. Git waits for the tool to exit before launching the next file. The
exit code of the application for each file determines whether the file
is marked resolved or not. You also have the option to explicitly run
git add <file> to mark it staged.
If there are several merge tools configured, Git chooses the first found from this list:
merge.toolconfiguration.$GIT_MERGE_TOOLenvironment variable.- Auto-detection from known installed tools.
Invoking the External Tool
For each conflicted file Example.swift Git creates
additional files seen here:
Example_BACKUP_70842.swift
Example_BASE_70842.swift
Example_LOCAL_70842.swift
Example_REMOTE_70842.swift
Example.swift
The suffix number changes for each invocation. Then it invokes the
tool with a command configured as we saw in Git Integration. For
abd the command is
abd --base Example_BASE_70842.swift --local Example_LOCAL_70842.swift --remote Example_REMOTE_70842.swift --result Example.swiftThe tool is supposed to remove the conflict markers and exit normally. This indicates the conflict have been solved.
Diff
For diffing, external tools are only useful for visual inspection.
Git ignores the return code when the application exits. If you invoke
git difftool, Git will enumerate the files changed and
launch the external tool for each pair of files.
Usually it’s better to just drag and drop the files you want to
compare. But if you rather compare all, run git difftool.
The external tool invoked is the first found from this list:
diff.toolconfiguration.$GIT_DIFF_TOOLenvironment variable.- Auto-detection from known tools in
$PATH. - Fallback to
vimdiff.