fix(git): carry the pathspec into GetBranchDiffAsync's fallback

This commit is contained in:
mika kuns
2026-08-11 08:32:53 +02:00
parent d3ba279b54
commit 1acd4c1734
2 changed files with 14 additions and 7 deletions
+13 -6
View File
@@ -139,16 +139,20 @@ public sealed class GitService
throw new InvalidOperationException($"git commit failed (exit {exitCode}): {stderr}"); throw new InvalidOperationException($"git commit failed (exit {exitCode}): {stderr}");
} }
public async Task<string> GetDiffAsync(string worktreePath, CancellationToken ct = default) public async Task<string> GetDiffAsync(
string worktreePath, IReadOnlyList<string>? paths = null, CancellationToken ct = default)
{ {
var (exitCode, stdout, stderr) = await RunGitAsync(worktreePath, var args = new List<string> { "diff", "HEAD" };
["diff", "HEAD"], ct); AppendPathFilter(args, paths);
var (exitCode, stdout, stderr) = await RunGitAsync(worktreePath, args, ct);
if (exitCode != 0) if (exitCode != 0)
throw new InvalidOperationException($"git diff HEAD failed (exit {exitCode}): {stderr}"); throw new InvalidOperationException($"git diff HEAD failed (exit {exitCode}): {stderr}");
// If nothing staged vs HEAD, try the index (untracked is never in diff) // If nothing staged vs HEAD, try the index (untracked is never in diff)
if (string.IsNullOrWhiteSpace(stdout)) if (string.IsNullOrWhiteSpace(stdout))
{ {
var (e2, s2, _) = await RunGitAsync(worktreePath, ["diff", "--cached"], ct); var cachedArgs = new List<string> { "diff", "--cached" };
AppendPathFilter(cachedArgs, paths);
var (e2, s2, _) = await RunGitAsync(worktreePath, cachedArgs, ct);
if (e2 == 0) return s2; if (e2 == 0) return s2;
} }
return stdout; return stdout;
@@ -167,8 +171,11 @@ public sealed class GitService
var (exitCode, stdout, _) = await RunGitAsync(worktreePath, args, ct); var (exitCode, stdout, _) = await RunGitAsync(worktreePath, args, ct);
if (exitCode == 0 && !string.IsNullOrWhiteSpace(stdout)) if (exitCode == 0 && !string.IsNullOrWhiteSpace(stdout))
return stdout; return stdout;
// Fallback: whatever the worktree has vs HEAD (uncommitted only). // Fallback: whatever the worktree has vs HEAD (uncommitted only). The same pathspec has to
return await GetDiffAsync(worktreePath, ct); // 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);
} }
/// <summary> /// <summary>
@@ -165,7 +165,7 @@ public sealed partial class DiffViewerViewModel : ViewModelBase
? await _git.GetCommitRangeDiffAsync(WorktreePath, BaseRef, HeadCommit, ct: ct) ? await _git.GetCommitRangeDiffAsync(WorktreePath, BaseRef, HeadCommit, ct: ct)
: BaseRef is not null : BaseRef is not null
? await _git.GetBranchDiffAsync(WorktreePath, BaseRef, ct: ct) ? await _git.GetBranchDiffAsync(WorktreePath, BaseRef, ct: ct)
: await _git.GetDiffAsync(WorktreePath, ct); : await _git.GetDiffAsync(WorktreePath, ct: ct);
} }
catch (Exception ex) catch (Exception ex)
{ {