From 558fe55acccbbb64b6c6098b58820715f33aeb45 Mon Sep 17 00:00:00 2001 From: Sidharth Menon Date: Mon, 5 Oct 2026 00:02:26 -0700 Subject: [PATCH 1/2] Reject invalid Git comparisons before launching the TUI AI assistance: implemented and tested with OpenAI Codex. Agent-Session: b7f96806-2bcb-4ee8-aca4-c5bedad0939a Agent-Session: 82924cb5-dcfa-42e4-abb0-ef40393249f8 Agent-Session: 01a10ad4-5daa-74b2-9479-9dca5e8b2572 Agent-Session: ea775653-fef8-47be-96ea-16815bdff22c --- src/cli.rs | 11 ++++++++--- tests/git_comparison.rs | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index e6fd2ed3f..52a5968a5 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -180,10 +180,10 @@ pub(crate) fn run(runtime: &tokio::runtime::Runtime) -> Result { } let streaming = args.format.is_some(); let metadata_or_quiet = args.quiet || args.metadata(); - if !streaming && !metadata_or_quiet { - return launch_tui(&frontend_args, true); - } if args.no_index { + if !streaming && !metadata_or_quiet { + return launch_tui(&frontend_args, true); + } return no_index( runtime, &args, @@ -194,6 +194,11 @@ pub(crate) fn run(runtime: &tokio::runtime::Runtime) -> Result { let repo = gix::discover(&location)?; let workspace = repo.workdir().unwrap_or(repo.git_dir()); let (comparison, paths) = select(&repo, &location, &args, has_separator)?; + if !streaming && !metadata_or_quiet { + // Reject invalid revisions before the UI takes over the terminal. + comparison.resolve(&repo)?; + return launch_tui(&frontend_args, true); + } let files = FileParams { paths, // `-M` conflicts with `--no-renames`; renames are on by default. diff --git a/tests/git_comparison.rs b/tests/git_comparison.rs index c521acdc3..abd382307 100644 --- a/tests/git_comparison.rs +++ b/tests/git_comparison.rs @@ -42,6 +42,27 @@ fn statuses(text: &str) -> Vec { .collect() } +#[test] +fn invalid_revision_range_is_rejected_before_the_terminal_ui() { + let dir = tempfile::tempdir().unwrap(); + let repo = gix::init(dir.path()).unwrap(); + commit(&repo, "base"); + commit(&repo, "head"); + + let output = diffr(dir.path(), &["HEAD^2..HEAD"]); + assert_eq!(output.status.code(), Some(2)); + assert!(output.stdout.is_empty()); + let stderr = String::from_utf8(output.stderr).unwrap(); + assert!( + stderr.contains("unknown revision or path \"HEAD^2..HEAD\""), + "{stderr}" + ); + + let output = diffr(dir.path(), &["HEAD^..HEAD"]); + let stderr = String::from_utf8(output.stderr).unwrap(); + assert!(stderr.contains("terminal UI needs a terminal"), "{stderr}"); +} + #[test] fn revisions_index_worktree_reverse_paths_and_stats_match_git() { let dir = tempfile::tempdir().unwrap(); From b289e6816fe8c740c80917e05bd51be6fa9ec24b Mon Sep 17 00:00:00 2001 From: Sidharth Menon Date: Mon, 5 Oct 2026 00:09:38 -0700 Subject: [PATCH 2/2] Flatten CLI frontend selection AI assistance: implemented and tested with OpenAI Codex. Agent-Session: b7f96806-2bcb-4ee8-aca4-c5bedad0939a Agent-Session: 82924cb5-dcfa-42e4-abb0-ef40393249f8 Agent-Session: 01a10ad4-5daa-74b2-9479-9dca5e8b2572 Agent-Session: ea775653-fef8-47be-96ea-16815bdff22c --- src/cli.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 52a5968a5..8082225f9 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -178,12 +178,12 @@ pub(crate) fn run(runtime: &tokio::runtime::Runtime) -> Result { } None => {} } - let streaming = args.format.is_some(); let metadata_or_quiet = args.quiet || args.metadata(); + let interactive = args.format.is_none() && !metadata_or_quiet; + if interactive && args.no_index { + return launch_tui(&frontend_args, true); + } if args.no_index { - if !streaming && !metadata_or_quiet { - return launch_tui(&frontend_args, true); - } return no_index( runtime, &args, @@ -194,7 +194,7 @@ pub(crate) fn run(runtime: &tokio::runtime::Runtime) -> Result { let repo = gix::discover(&location)?; let workspace = repo.workdir().unwrap_or(repo.git_dir()); let (comparison, paths) = select(&repo, &location, &args, has_separator)?; - if !streaming && !metadata_or_quiet { + if interactive { // Reject invalid revisions before the UI takes over the terminal. comparison.resolve(&repo)?; return launch_tui(&frontend_args, true);