Skip to content

feat(diff): default dunk diff to staged + unstaged, add --unstaged#11

Merged
amix merged 1 commit into
mainfrom
amix/diff-staged-unstaged-default
May 19, 2026
Merged

feat(diff): default dunk diff to staged + unstaged, add --unstaged#11
amix merged 1 commit into
mainfrom
amix/diff-staged-unstaged-default

Conversation

@amix
Copy link
Copy Markdown
Owner

@amix amix commented May 19, 2026

Context

dunk diff diffed the working tree against the index, so anything already git added silently dropped out of the review. A quick dunk diff should show everything you've touched since the last commit.

What was changed

  • dunk diff now defaults to working tree vs HEAD (staged + unstaged together). Untracked files still included.
  • --staged/--cached → index-vs-HEAD only. New --unstaged → working-tree-vs-index only.
  • Working-tree scope is encoded purely as the comparison base (range); no new input field. classifyVcsScope is the single source for title + command label so the mapping can't drift.
  • Unborn HEAD (repo with no commits): resolveWorktreeBaseRef falls back to git's empty tree (resolved per object format, SHA-1/SHA-256), so staged-but-uncommitted files still show instead of git diff HEAD hard-failing. Fallback is loader-local; the session keeps the original HEAD base so a later reload re-evaluates it. The watch-signature path resolves the same base so --watch doesn't crash in a fresh repo.
  • --staged+--unstaged, --branch+--unstaged, and --unstaged <revision> are rejected with actionable errors.

Reviewed with Doistbot (2 rounds) and an expert pass (Codex); applied the P1 unborn-HEAD fix, dropped a staleness-prone HEAD-existence cache, and added SHA-256 regression coverage.

Out of scope

  • --branch --watch already used a plain git diff --raw signature (pre-existing; watch never resolved the merge-base). Not introduced or worsened here — left for a follow-up.
  • Extracting a shared git-ref probe with branchReview.ts (cross-module refactor).

Refs

CHANGELOG under ## [Unreleased].

🤖 Generated with Claude Code

`dunk diff` compared the working tree against the index, so anything
already `git add`ed silently dropped out of the review. Default it to
working tree vs `HEAD` (range "HEAD") so one `dunk diff` shows
everything since the last commit. `--staged`/`--cached` keeps
index-vs-`HEAD`; new `--unstaged` scopes to working-tree-vs-index.

Working-tree scope stays encoded purely as the comparison base — no new
input field. `classifyVcsScope` is the single source for title/label so
the mapping can't drift. A repo with no commits has an unborn HEAD where
`git diff HEAD` would fail, so the loader and the watch-signature path
resolve the base through `resolveWorktreeBaseRef`, which falls back to
git's empty tree (still surfaces staged-but-uncommitted files). The
fallback is loader-local; the session keeps the original HEAD base so a
later reload re-evaluates it. HEAD existence is cached per repo so the
common already-committed path adds no extra git spawn after the first.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@amix amix marked this pull request as ready for review May 19, 2026 09:15
@amix amix merged commit 2e357cf into main May 19, 2026
2 checks passed
@amix amix deleted the amix/diff-staged-unstaged-default branch May 19, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant