From 1acd4c17341f740c7f8ab470775ab3185d09f217 Mon Sep 17 00:00:00 2001 From: mika kuns Date: Tue, 11 Aug 2026 08:32:53 +0200 Subject: [PATCH] fix(git): carry the pathspec into GetBranchDiffAsync's fallback --- src/ClaudeDo.Data/Git/GitService.cs | 19 +++++++++++++------ .../ViewModels/Modals/DiffViewerViewModel.cs | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/ClaudeDo.Data/Git/GitService.cs b/src/ClaudeDo.Data/Git/GitService.cs index f998ae90..ac0a44a4 100644 --- a/src/ClaudeDo.Data/Git/GitService.cs +++ b/src/ClaudeDo.Data/Git/GitService.cs @@ -139,16 +139,20 @@ public sealed class GitService throw new InvalidOperationException($"git commit failed (exit {exitCode}): {stderr}"); } - public async Task GetDiffAsync(string worktreePath, CancellationToken ct = default) + public async Task GetDiffAsync( + string worktreePath, IReadOnlyList? paths = null, CancellationToken ct = default) { - var (exitCode, stdout, stderr) = await RunGitAsync(worktreePath, - ["diff", "HEAD"], ct); + var args = new List { "diff", "HEAD" }; + AppendPathFilter(args, paths); + var (exitCode, stdout, stderr) = await RunGitAsync(worktreePath, args, ct); if (exitCode != 0) throw new InvalidOperationException($"git diff HEAD failed (exit {exitCode}): {stderr}"); // If nothing staged vs HEAD, try the index (untracked is never in diff) if (string.IsNullOrWhiteSpace(stdout)) { - var (e2, s2, _) = await RunGitAsync(worktreePath, ["diff", "--cached"], ct); + var cachedArgs = new List { "diff", "--cached" }; + AppendPathFilter(cachedArgs, paths); + var (e2, s2, _) = await RunGitAsync(worktreePath, cachedArgs, ct); if (e2 == 0) return s2; } return stdout; @@ -167,8 +171,11 @@ public sealed class GitService var (exitCode, stdout, _) = await RunGitAsync(worktreePath, args, ct); if (exitCode == 0 && !string.IsNullOrWhiteSpace(stdout)) return stdout; - // Fallback: whatever the worktree has vs HEAD (uncommitted only). - return await GetDiffAsync(worktreePath, ct); + // Fallback: whatever the worktree has vs HEAD (uncommitted only). The same pathspec has to + // come along — a filter makes an empty ranged diff the common case (the caller asked for + // paths this range never touched), and an unfiltered fallback would answer that with the + // whole worktree diff, the exact opposite of what was requested. + return await GetDiffAsync(worktreePath, paths, ct); } /// diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/DiffViewerViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/DiffViewerViewModel.cs index 3ef7285b..f8003bc6 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/DiffViewerViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/DiffViewerViewModel.cs @@ -165,7 +165,7 @@ public sealed partial class DiffViewerViewModel : ViewModelBase ? await _git.GetCommitRangeDiffAsync(WorktreePath, BaseRef, HeadCommit, ct: ct) : BaseRef is not null ? await _git.GetBranchDiffAsync(WorktreePath, BaseRef, ct: ct) - : await _git.GetDiffAsync(WorktreePath, ct); + : await _git.GetDiffAsync(WorktreePath, ct: ct); } catch (Exception ex) {