# git diff-tree: Usage, Options & Common CI Errors

> git diff-tree is the plumbing command that compares two tree objects. Reference for -r, --name-only, --no-commit-id, and parsing changed files in CI hooks.

Source: https://latchkey.dev/learn/command-reference/git-diff-tree  
Updated: 2026-06-25

git diff-tree compares the contents of two tree objects at the plumbing level.

When a hook or pipeline needs the exact list of files a commit changed, diff-tree is the stable, scriptable answer. It is the engine behind much of git log and is common in post-receive hooks.

## What it does

git diff-tree compares two tree objects (or the trees of two commits) and prints the differences. With -r it recurses into subtrees, and its output format is stable enough to parse in scripts.

## Common usage

```Terminal
git diff-tree -r --name-only HEAD
git diff-tree --no-commit-id --name-only -r <sha>
git diff-tree -r <old-sha> <new-sha>
git diff-tree --root -r <first-commit>
```

## Options

| Flag | What it does |
| --- | --- |
| -r | Recurse into subtrees |
| --name-only | Print only changed file names |
| --name-status | Names plus add/modify/delete status |
| --no-commit-id | Omit the leading commit SHA line |
| --root | Show the full diff for a root commit |

## Common errors in CI

A root (first) commit prints nothing because it has no parent; pass --root to diff it against the empty tree. Forgetting --no-commit-id leaves the commit SHA as the first output line, which then leaks into file lists when scripts read line by line.

## Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

```.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached
```

> `git rev-parse --abbrev-ref HEAD` returns the literal string `HEAD` on a detached checkout rather than a branch name. On GitHub Actions read `github.ref_name` instead; the git command cannot know what it was checked out for.

## FAQ

### git diff-tree: Usage, Options & Common CI Errors?

When a hook or pipeline needs the exact list of files a commit changed, diff-tree is the stable, scriptable answer. It is the engine behind much of git log and is common in post-receive hooks.

### What it does?

git diff-tree compares two tree objects (or the trees of two commits) and prints the differences. With -r it recurses into subtrees, and its output format is stable enough to parse in scripts.

### Common errors in CI?

A root (first) commit prints nothing because it has no parent; pass --root to diff it against the empty tree. Forgetting --no-commit-id leaves the commit SHA as the first output line, which then leaks into file lists when scripts read line by line.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
