fix(cli): /diff shows clear error when not in a git repo

Previously claw --resume <session> /diff would produce:
  'git diff --cached failed: error: unknown option `cached\''
when the CWD was not inside a git project, because git falls back to
--no-index mode which does not support --cached.

Two fixes:
1. render_diff_report_for() checks 'git rev-parse --is-inside-work-tree'
   before running git diff, and returns a human-readable message if not
   in a git repo:
     'Diff\n  Result  no git repository\n  Detail  <cwd> is not inside a git project'
2. resume /diff now uses std::env::current_dir() instead of the session
   file's parent directory as the CWD for the diff (session parent dir
   is the .claw/sessions/<id>/ directory, never a git repo).

159 CLI tests pass, fmt clean.
This commit is contained in:
YeonGyu-Kim
2026-04-09 20:04:21 +09:00
parent 3ed27d5cba
commit aef85f8af5

View File

@@ -2708,7 +2708,7 @@ fn run_resume_command(
SlashCommand::Diff => Ok(ResumeCommandOutcome { SlashCommand::Diff => Ok(ResumeCommandOutcome {
session: session.clone(), session: session.clone(),
message: Some(render_diff_report_for( message: Some(render_diff_report_for(
session_path.parent().unwrap_or_else(|| Path::new(".")), &std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
)?), )?),
json: None, json: None,
}), }),
@@ -5242,6 +5242,21 @@ fn render_diff_report() -> Result<String, Box<dyn std::error::Error>> {
} }
fn render_diff_report_for(cwd: &Path) -> Result<String, Box<dyn std::error::Error>> { fn render_diff_report_for(cwd: &Path) -> Result<String, Box<dyn std::error::Error>> {
// Verify we are inside a git repository before calling `git diff`.
// Running `git diff --cached` outside a git tree produces a misleading
// "unknown option `cached`" error because git falls back to --no-index mode.
let in_git_repo = std::process::Command::new("git")
.args(["rev-parse", "--is-inside-work-tree"])
.current_dir(cwd)
.output()
.map(|o| o.status.success())
.unwrap_or(false);
if !in_git_repo {
return Ok(format!(
"Diff\n Result no git repository\n Detail {} is not inside a git project",
cwd.display()
));
}
let staged = run_git_diff_command_in(cwd, &["diff", "--cached"])?; let staged = run_git_diff_command_in(cwd, &["diff", "--cached"])?;
let unstaged = run_git_diff_command_in(cwd, &["diff"])?; let unstaged = run_git_diff_command_in(cwd, &["diff"])?;
if staged.trim().is_empty() && unstaged.trim().is_empty() { if staged.trim().is_empty() && unstaged.trim().is_empty() {