From 2c85b9a377b0b4985bdc9e463fe6053d5d97f29d Mon Sep 17 00:00:00 2001 From: Umputun Date: Tue, 1 Sep 2026 12:15:41 -0500 Subject: [PATCH 1/3] docs: use exact ranges for last-commit reviews --- .claude-plugin/skills/revdiff/references/usage.md | 2 +- README.md | 13 +++++++------ plugins/codex/README.md | 2 +- plugins/codex/skills/revdiff/references/usage.md | 2 +- plugins/pi/README.md | 2 +- plugins/pi/skills/revdiff/SKILL.md | 2 +- site/docs.html | 15 ++++++++------- site/index.html | 6 +++--- 8 files changed, 23 insertions(+), 21 deletions(-) diff --git a/.claude-plugin/skills/revdiff/references/usage.md b/.claude-plugin/skills/revdiff/references/usage.md index a045fa14..d0c0619d 100644 --- a/.claude-plugin/skills/revdiff/references/usage.md +++ b/.claude-plugin/skills/revdiff/references/usage.md @@ -11,7 +11,7 @@ revdiff # review uncommitted changes revdiff main # review changes against a branch revdiff --staged # review staged changes revdiff --untracked # show untracked files in the tree -revdiff HEAD~1 # review last commit +revdiff HEAD~1 HEAD # review last commit revdiff main feature # diff between two refs revdiff main..feature # same as above, git dot-dot syntax revdiff main...feature # changes since feature diverged from main diff --git a/README.md b/README.md index 99c5585e..8d6661df 100644 --- a/README.md +++ b/README.md @@ -129,17 +129,17 @@ Priority: agterm → tmux → Zellij → herdr → kitty → wezterm/Kaku → cm ``` /revdiff -- smart detection: uncommitted, last commit, or branch diff -/revdiff HEAD~1 -- review last commit +/revdiff HEAD~1 HEAD -- review last commit /revdiff main -- review current branch against main /revdiff --staged -- review staged changes only -/revdiff HEAD~3 -- review last 3 commits +/revdiff HEAD~3 HEAD -- review last 3 commits ``` **Use with free text** (no slash command needed): ``` "review diff" -- smart detection, same as /revdiff -"review diff HEAD~1" -- last commit +"review diff HEAD~1 HEAD" -- last commit "review diff against main" -- branch diff "review changes from last 2 days" -- Claude resolves the ref automatically "revdiff for staged changes" -- staged only @@ -219,7 +219,7 @@ Useful args: ```text /revdiff -- detect uncommitted, staged, or branch changes, then open revdiff -/revdiff HEAD~1 -- review last commit +/revdiff HEAD~1 HEAD -- review last commit /revdiff main -- review against main /revdiff --staged -- review staged changes /revdiff --untracked -- include untracked files in working-tree review @@ -327,7 +327,7 @@ The setup script copies files to `~/.config/opencode/` and registers the plan-re ```text /revdiff -- review git diff with revdiff TUI -/revdiff HEAD~3 -- review last 3 commits +/revdiff HEAD~3 HEAD -- review last 3 commits ``` The plan-review plugin automatically launches revdiff when the assistant exits plan mode, letting you annotate before approval. @@ -358,6 +358,7 @@ revdiff [OPTIONS] [base] [against] Positional arguments support several forms: - `revdiff` — uncommitted changes - `revdiff HEAD~3` — diff a single ref against the working tree +- `revdiff HEAD~1 HEAD` — review exactly the last commit - `revdiff main feature` — diff between two refs - `revdiff main..feature` — same as above, using git's dot-dot syntax - `revdiff main...feature` — changes since `feature` diverged from `main` @@ -554,7 +555,7 @@ revdiff main revdiff --staged # review last commit -revdiff HEAD~1 +revdiff HEAD~1 HEAD # diff between two refs revdiff main feature diff --git a/plugins/codex/README.md b/plugins/codex/README.md index c9320e68..eb02a044 100644 --- a/plugins/codex/README.md +++ b/plugins/codex/README.md @@ -56,7 +56,7 @@ Interactive diff review with inline annotations. ```text /revdiff — auto-detect ref (uncommitted, staged, branch vs master, or last commit) -/revdiff HEAD~3 — review last 3 commits +/revdiff HEAD~3 HEAD — review last 3 commits /revdiff main feature — two-ref diff /revdiff all files — browse all tracked files /revdiff path/to/file — review a single file diff --git a/plugins/codex/skills/revdiff/references/usage.md b/plugins/codex/skills/revdiff/references/usage.md index d7873d72..1fe3b4f3 100644 --- a/plugins/codex/skills/revdiff/references/usage.md +++ b/plugins/codex/skills/revdiff/references/usage.md @@ -11,7 +11,7 @@ revdiff # review uncommitted changes revdiff main # review changes against a branch revdiff --staged # review staged changes revdiff --untracked # show untracked files in the tree -revdiff HEAD~1 # review last commit +revdiff HEAD~1 HEAD # review last commit revdiff main feature # diff between two refs revdiff main..feature # same as above, git dot-dot syntax revdiff main...feature # changes since feature diverged from main diff --git a/plugins/pi/README.md b/plugins/pi/README.md index 3e8baf1f..c94f163f 100644 --- a/plugins/pi/README.md +++ b/plugins/pi/README.md @@ -38,7 +38,7 @@ Useful args: ```text /revdiff -- detect uncommitted, staged, or branch changes, then open revdiff -/revdiff HEAD~1 -- review last commit +/revdiff HEAD~1 HEAD -- review last commit /revdiff main -- review against main /revdiff --staged -- review staged changes /revdiff --untracked -- include untracked files in working-tree review diff --git a/plugins/pi/skills/revdiff/SKILL.md b/plugins/pi/skills/revdiff/SKILL.md index a035bd07..c50e3433 100644 --- a/plugins/pi/skills/revdiff/SKILL.md +++ b/plugins/pi/skills/revdiff/SKILL.md @@ -18,7 +18,7 @@ Reference resolution rules: - Accept natural language. Resolve the user's requested target to concrete revdiff args before launching. - If the request identifies another working directory (for example `in ~/source/repo`), use that directory for any git/ref/path resolution, omit that directory phrase from the revdiff args, and pass the directory as the `revdiff_review` tool's `cwd` parameter. -- For commit-count requests, use the matching git rev: `prev commit`, `previous commit`, `last commit` → `HEAD~1`; `head-3`, `head 3`, `HEAD~3`, `previous 3 commits`, `last 3 commits` → `HEAD~3`. +- For natural-language commit-count requests, use two refs: `prev commit`, `previous commit`, `last commit` → `HEAD~1 HEAD`; `head-3`, `head 3`, `previous 3 commits`, `last 3 commits` → `HEAD~3 HEAD`. - For tag requests, resolve the actual tag first. `last tag` or `latest tag` → run `git describe --tags --abbrev=0`, then pass that tag as `args`. - For date requests, resolve the commit first. Examples: `2 weeks ago`, `yesterday`, `last Friday` → run `git rev-list -1 --before= HEAD`, then pass the resulting commit hash as `args`. - For file targets, use `args: "--only "`. diff --git a/site/docs.html b/site/docs.html index f0431f22..d497282a 100644 --- a/site/docs.html +++ b/site/docs.html @@ -135,7 +135,7 @@

Command inside pi

/revdiff [args]

Useful args

/revdiff -- detect uncommitted, staged, or branch changes, then open revdiff -/revdiff HEAD~1 -- review last commit +/revdiff HEAD~1 HEAD -- review last commit /revdiff main -- review against main /revdiff --staged -- review staged changes /revdiff --untracked -- include untracked files in working-tree review @@ -180,6 +180,7 @@

Usage

  • revdiff — uncommitted changes
  • revdiff HEAD~3 — diff a single ref against the working tree
  • +
  • revdiff HEAD~1 HEAD — review exactly the last commit
  • revdiff main feature — diff between two refs
  • revdiff main..feature — same as above, git dot-dot syntax
  • revdiff main...feature — changes since feature diverged from main
  • @@ -197,7 +198,7 @@

    Examples

    revdiff --staged # review last commit -revdiff HEAD~1 +revdiff HEAD~1 HEAD # diff between two refs revdiff main feature @@ -722,14 +723,14 @@

    Terminal support

    Plugin usage

    Slash commands

    /revdiff -- smart detection: uncommitted, last commit, or branch diff -/revdiff HEAD~1 -- review last commit +/revdiff HEAD~1 HEAD -- review last commit /revdiff main -- review current branch against main -/revdiff HEAD~3 -- review last 3 commits +/revdiff HEAD~3 HEAD -- review last 3 commits /revdiff --staged -- review staged changes only /revdiff all files -- browse all tracked files

    Natural language

    "review diff" -- same as /revdiff, smart detection -"review diff HEAD~1" -- last commit +"review diff HEAD~1 HEAD" -- last commit "review diff against main" -- branch diff "review changes from last 2 days" -- Claude resolves the ref "revdiff for staged changes" -- staged only @@ -801,7 +802,7 @@

    Skills

Codex treats exit code 10 as success-with-annotations and keeps captured output.

/revdiff # auto-detect ref -/revdiff HEAD~3 # review last 3 commits +/revdiff HEAD~3 HEAD # review last 3 commits /revdiff-plan # review last Codex response

Differences from Claude Code plugin

@@ -825,7 +826,7 @@

Usage

  • Plan-review plugin — automatically launches revdiff when the assistant exits plan mode, injecting annotations back as user messages
  • /revdiff # auto-detect ref -/revdiff HEAD~3 # review last 3 commits +/revdiff HEAD~3 HEAD # review last 3 commits /revdiff --staged # review staged changes
    diff --git a/site/index.html b/site/index.html index b620395e..56f98f1d 100644 --- a/site/index.html +++ b/site/index.html @@ -410,16 +410,16 @@

    Annotate & fix

    Slash commands

    /revdiff -- smart detection: uncommitted, last commit, or branch diff -/revdiff HEAD~1 -- review last commit +/revdiff HEAD~1 HEAD -- review last commit /revdiff main -- review current branch against main -/revdiff HEAD~3 -- review last 3 commits +/revdiff HEAD~3 HEAD -- review last 3 commits /revdiff --staged -- review staged changes only /revdiff all files -- browse all tracked files in the project

    Natural language

    "review diff" -- same as /revdiff, smart detection -"review diff HEAD~1" -- last commit +"review diff HEAD~1 HEAD" -- last commit "review diff against main" -- branch diff "review changes from last 2 days" -- Claude resolves the ref "revdiff for staged changes" -- staged only From 733c91f430a97ffb87c597b2fb5867e2dd775055 Mon Sep 17 00:00:00 2001 From: Umputun Date: Tue, 1 Sep 2026 12:32:41 -0500 Subject: [PATCH 2/3] docs: add backlog item for jj HEAD^ ref mistranslation (*Jj).translateRef has one broad HasPrefix("HEAD^") branch answering two different inputs with parents(@-). HEAD^! is git syntax jj does not support and becomes a grandparent-to-working-copy diff with no error, the only backend that fails silently. HEAD^N for N>1 is a knowingly approximate parent set. Found while investigating #335, not caused by it. The fix is left open because rejecting HEAD^N is a behavior change, not a bug fix. --- ...-head-caret-refs-silently-mistranslated.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 docs/backlog/jj-head-caret-refs-silently-mistranslated.md diff --git a/docs/backlog/jj-head-caret-refs-silently-mistranslated.md b/docs/backlog/jj-head-caret-refs-silently-mistranslated.md new file mode 100644 index 00000000..42ef783b --- /dev/null +++ b/docs/backlog/jj-head-caret-refs-silently-mistranslated.md @@ -0,0 +1,22 @@ +# jj mistranslates `HEAD^!` and approximates `HEAD^N` + +`(*Jj).translateRef` in `app/diff/jj.go` has a broad `strings.HasPrefix(ref, "HEAD^")` branch that +swallows two different inputs and answers both with `parents(@-)`: + +- `HEAD^!` is git revision-set syntax jj does not support. It becomes `parents(@-)`, and + `diffRangeFlags` then builds `--from parents(@-) --to @`, so the user gets a grandparent-to-working-copy + diff that looks plausible and carries no error, while git rejects `HEAD^!..HEAD` for the commit log + and hg emits the invalid revset `p!(.)`, so jj is the only backend that fails silently here. +- `HEAD^N` for N greater than 1 means the Nth parent. The branch's own comment admits jj cannot single + out an individual parent in one revset step and calls `parents(@-)` a best-effort approximation. + +Found while investigating #335 (closed as not planned); not part of that issue and not caused by it. +hg's equivalent needs no change: its `pN(.)` mapping is correct. + +Not pre-deciding the fix. Two options, and they can differ per input: fail closed on a malformed +suffix so the user sees a rejection instead of wrong data, or implement exact Nth-parent selection if +jj can express it. Rejecting `HEAD^N` is a behavior change beyond a bug fix, so it needs a decision. + +A regression must assert at the public operation, e.g. `ChangedFiles("HEAD^!", false)` returning an +error against a real jj repo. Asserting that `translateRef` returns the raw string does not prove the +user ever sees the rejection. From e94566c88c305188702015ab3b9857cdcb40a8c7 Mon Sep 17 00:00:00 2001 From: Umputun Date: Tue, 1 Sep 2026 12:41:28 -0500 Subject: [PATCH 3/3] docs(pi): show the exact-commit form in the command examples The natural-language rule above resolves "last commit" to HEAD~1 HEAD, so listing only the bare ref left the same file recommending two different spellings for the same request. The bare form stays: an explicit single ref against the working tree is a legitimate thing to type. Raised by Copilot on #347. --- plugins/pi/skills/revdiff/SKILL.md | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/pi/skills/revdiff/SKILL.md b/plugins/pi/skills/revdiff/SKILL.md index c50e3433..e1fe5447 100644 --- a/plugins/pi/skills/revdiff/SKILL.md +++ b/plugins/pi/skills/revdiff/SKILL.md @@ -72,6 +72,7 @@ When annotations arrive from `/revdiff` or `revdiff_review`: ```text /revdiff /revdiff HEAD~1 +/revdiff HEAD~1 HEAD /revdiff main /revdiff --staged /revdiff --untracked