KuSh: the in-progress state line ("rebase in progress", "merge in
progress. unresolved conflicts", etc.) is enough — LLMs know which git
commands resolve each state, so the per-state hint list was noise.
Removes STATE_HINTS and extract_state_hint, and reduces extract_state_header
to a short walk that returns the first detected state summary or None.
Existing per-state tests now assert the exact compact summary.
- Drop redundant LANG=C env (LC_ALL=C is sufficient).
- Replace nested if/else chains in detect_status_state and
extract_state_hint with const slices + iter for readability.
- Drop the 2-space indent prefix on hint lines — adds nothing for
machine consumption.
Default `rtk git status` runs `git status --porcelain -b` to build its
compact view, but porcelain v1 omits the state header git prints when a
rebase, merge, cherry-pick, revert, bisect, am, or sparse checkout is in
progress. That header is correctness-critical — hiding "You are currently
editing a commit while rebasing..." leaves the user thinking the repo is
clean when it isn't.
`run_status` already captures plain `git status` output as `raw_output`
for tracking, so this fix adds `extract_state_header` to pull the state
block out of it and prepends the block to the compact output. Returns
`None` when nothing is in progress so clean repos are unchanged.
Covered states: interactive / regular rebase, merge-with-unmerged-paths,
"still merging after conflicts fixed", cherry-pick, revert, bisect, am,
sparse checkout. Preserves the directive hints git prints alongside
(`git rebase --continue`, `git commit --amend`, `git bisect reset`,
etc.), while still filtering generic `(use "git add")` / `(use "git
restore")` noise.
Design principle: Correctness vs Token Savings — never hide information
that changes the user's understanding of repo state.
Branch names containing '/' (e.g. feature/user-auth, main...feature/auth)
were incorrectly treated as file paths by the string heuristic in
normalize_diff_args, causing '--' to be injected before them and making
git treat them as pathspecs — resulting in silent empty output (exit 0).
Replace looks_like_path() with a three-tier detection strategy:
- Explicit path prefixes (. ~) → always a path, no filesystem check needed
- Contains path separator (/ \) → use filesystem existence to distinguish
branch names (feature/auth, not on disk) from real paths (src/main.rs)
- Bare word with no separator → never inject '--', regardless of filesystem
state (avoids misfire when a file shares a name with a branch/ref)
Introduce normalize_diff_args_impl with injectable path-checker for
testability. Update all existing tests to use mock existence checks.
Add three regression tests: branch-with-slash, range-with-slash, and
bare-word-that-exists-on-disk.
Fixes: #1431
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
clap's trailing_var_arg=true silently drops -- when it appears as the first
positional argument. This caused `rtk git diff -- <path>` to arrive in
run_diff without the separator, making git treat the path as a revision and
emit "fatal: ambiguous argument". Adds normalize_diff_args() which re-inserts
-- before the first path-like argument (contains /, \, starts with . or ~)
when -- is absent from the args vec. The fix is a no-op when -- is already
present (e.g. rtk git diff HEAD -- file preserves the separator correctly).
Generated by Claude Code
Vibe coded by ousamabenyounes
Co-Authored-By: Claude <noreply@anthropic.com>
Command::output() sets stdin to Stdio::piped() by default, creating an
empty pipe instead of inheriting the terminal. SSH signing tools
(1Password, YubiKey, gpg-agent with pinentry) need TTY access on stdin
for passphrase prompts or agent communication. This caused signatures
to be silently dropped — commits succeeded but without gpgsig headers.
Fix: add .stdin(Stdio::inherit()) to git commit and git push commands
so they inherit the parent's stdin (terminal or hook pipe). Output
capture via stdout/stderr pipes is preserved.
Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>