Progress:
TIER 3 · MODULE 25· Expert

git diff-pairs

Plumbing for tools that already know which blobs to diff.

🎯 What & why

Plumbing that diffs explicit blob pairs you hand it on stdin. Skips the tree walk entirely so callers that already know which blobs to compare don't pay for one.

🧠 Mental model

Think of it as the tail end of the diff pipeline: you've done the discovery, this command does the rendering. Input is one record per pair, NUL-terminated, in the same shape diff-tree would emit with -z --raw.

🛠️ Synopsis

git diff-pairs [<diff-options>] -z <path>
git diff-pairs [<diff-options>] -z < <input>

Each input record:
  :<mode1> SP <mode2> SP <oid1> SP <oid2> SP <status> NUL <path1> NUL [<path2> NUL]

🎚️ Switches & options

FlagWhat it does
-zRequired. NUL-terminated input and output; pathnames are not quoted.
<input>File to read records from; default is stdin.
-p / --patchEmit a unified patch for each pair (default behavior for a diff command).
--rawEmit the raw diff format instead of patches.
--name-onlyList only paths touched by the supplied pairs.
--statShow a diffstat summarizing the supplied pairs.

💡 Use cases

🧪 Examples

Pipe diff-tree records straight back as patches
git diff-tree -r -z --raw HEAD^ HEAD | git diff-pairs -z -p
Render a single hand-built pair
printf ':100644 100644 %s %s M\0README.md\0' $oid1 $oid2 | git diff-pairs -z -p
Stat-only summary from a cached record file
git diff-pairs -z --stat <pairs.bin
Name-only output for downstream tooling
git diff-pairs -z --name-only <pairs.bin

🎓 Recommendations

🪤 Common pitfalls

🔗 Related modules

📝 Quiz

Hit each option, then Check answers. Score is recorded; Next is always open.