How to build a git diff driver

2026-05-15 · source · source ↗ · raw capture

Jamie Tanna's guide to writing an external diff tool for git, written after discovering a gap in discoverable documentation. Covers the 7-argument interface git passes to external diff drivers, the /dev/null convention for file creation/deletion, and a worked example using oasdiff for OpenAPI spec diffs.

Summary

"How to write an external tool for git diff to delegate complex diffs to."

Motivation

Tanna had meant to write this "since November 2024." Working on renovate-packagedata-diff, he found "there seemed to be a lack of documentation around how to do it." While "some documentation in the Git Diffs man page" exists, it "wasn't exactly well discoverable."

A nudge came from Andrew Nesbitt's post on Git Diff Drivers, plus Tanna's own work diffing OpenAPI specs with oasdiff.

Arguments

Git passes 7 arguments to the external tool:

  1. Filename in the repo
  2. Path to the "before" file
  3. SHA-1 hash of the "before" file
  4. Octal mode of the "before" file
  5. Path to the "after" file
  6. SHA-1 hash of the "after" file
  7. Octal mode of the "after" file

Special cases

Also: check for GIT_PAGER_IN_USE environment variable if your command needs to handle both regular args and git diff args.

Example: oasdiff driver

#!/usr/bin/env bash

if "$2" == "/dev/null"; then
    echo "$1 was added"
    exit 0
elif "$5" == "/dev/null"; then
    echo "$1 was deleted"
    exit 0
fi

oasdiff changelog "$2" "$5" --color always

The author notes this "doesn't handle any changes in permissions" and suggests it "may be worth using the SHA-1 checksums of the files to cache the resulting diffs."

Related links