In a colocated jj repo, jj does not maintain git's index for git's own
consumption. git can therefore report an unmodified tracked file as a
whole-file add: for tests/integration/test_texttoentities_endpoint.py in
the IO repo, `git ls-tree HEAD` and `git ls-files -s` both showed the same
blob, yet `git status` reported `AM` and `git diff --cached --unified=0`
emitted a single `@@ -0,0 +1,330 @@` hunk.
shush treats every line in that hunk as agent-changed, so `--changes-only`
stripped all six comments from a file the agent had never touched (`jj diff`
confirmed 0 insertions). Diffing against HEAD instead of the index does not
help: it is poisoned the same way.
jj is authoritative when present, so DetectRepo now prefers `jj root` and
the three change queries route to `jj diff --git --context=0`. jj has no
staging area, so --staged, --unstaged and --changes-only all resolve to the
working-copy change; GetChangesOnly short-circuits so files are not
duplicated across the staged and unstaged passes.
Empty line ranges are overloaded to mean "process the whole file" (untracked
semantics). A deletion-only change parses to zero ranges, which would have
made shush strip an entire file whose only edit removed lines, so such files
are now skipped. New files still get correct full-file ranges from jj's
`@@ -0,0 +1,N @@` hunk, so they do not need the fallback.
Pagers are disabled explicitly on every git and jj invocation so output
stays machine-parseable regardless of the user's config.
- Return empty line ranges when git diff fails for non-tracked files
- Prevents hook failures on .claude/settings.local.json and similar files
- Improves robustness when processing files outside git tracking
- Add GitStatus, FileChange, LineRange types for git integration
- Implement DetectRepo() for repository detection
- Add GetStagedChanges() and GetUnstagedChanges() functions
- Create ParseDiffUnified() for git diff parsing
- Add line range utilities for precise change targeting
- Include comprehensive test suite for git operations