diff --git a/internal/diff/git.go b/internal/diff/git.go index 33254f2..765516b 100644 --- a/internal/diff/git.go +++ b/internal/diff/git.go @@ -115,14 +115,14 @@ func (p *Provider) GetDiff(ctx context.Context) ([]model.Diff, error) { if base == "" { return nil, fmt.Errorf("cannot find merge-base between %s and %s", p.from, p.to) } - out, err := p.runGit(ctx, "diff", "--no-ext-diff", "--no-textconv", "--no-color", "-U"+fmt.Sprint(DiffContextLines), base, p.to, "--") + out, err := p.runGit(ctx, "diff", "--no-ext-diff", "--no-textconv", "--src-prefix=a/", "--dst-prefix=b/", "--no-color", "-U"+fmt.Sprint(DiffContextLines), base, p.to, "--") if err != nil { return nil, fmt.Errorf("git diff failed: %w", err) } combined.WriteString(out) case ModeCommit: - out, err := p.runGit(ctx, "show", "--no-ext-diff", "--no-textconv", "--no-color", "-U"+fmt.Sprint(DiffContextLines), p.commit) + out, err := p.runGit(ctx, "show", "--no-ext-diff", "--no-textconv", "--src-prefix=a/", "--dst-prefix=b/", "--no-color", "-U"+fmt.Sprint(DiffContextLines), p.commit) if err != nil { return nil, fmt.Errorf("git show failed: %w", err) } @@ -265,14 +265,14 @@ func (p *Provider) computeMergeBase(ctx context.Context, from, to string) string } func (p *Provider) workspaceTrackedDiff(ctx context.Context) (string, error) { - out, err := p.runGit(ctx, "diff", "--no-ext-diff", "--no-textconv", "HEAD", "--no-color", "-U"+fmt.Sprint(DiffContextLines), "--") + out, err := p.runGit(ctx, "diff", "--no-ext-diff", "--no-textconv", "--src-prefix=a/", "--dst-prefix=b/", "HEAD", "--no-color", "-U"+fmt.Sprint(DiffContextLines), "--") if err == nil && out != "" { return out, nil } if ctx.Err() != nil { return "", ctx.Err() } - return p.runGit(ctx, "diff", "--no-ext-diff", "--no-textconv", "--staged", "--no-color", "-U"+fmt.Sprint(DiffContextLines), "--") + return p.runGit(ctx, "diff", "--no-ext-diff", "--no-textconv", "--src-prefix=a/", "--dst-prefix=b/", "--staged", "--no-color", "-U"+fmt.Sprint(DiffContextLines), "--") } func (p *Provider) untrackedFileDiffs(ctx context.Context) ([]string, error) { diff --git a/internal/diff/git_test.go b/internal/diff/git_test.go index 7410857..b414b4e 100644 --- a/internal/diff/git_test.go +++ b/internal/diff/git_test.go @@ -97,6 +97,33 @@ func TestWorkspaceDiffSurvivesExternalDiffTool(t *testing.T) { } } +// TestCommitDiffSurvivesExternalDiffTool covers the ModeCommit call site +// (git show ), which likewise must pass --no-ext-diff so that a +// user's external diff tool does not break single-commit analysis. +func TestCommitDiffSurvivesExternalDiffTool(t *testing.T) { + repo := initRepoWithChange(t) + + runGitTest(t, repo, "add", "sample.txt") + runGitTest(t, repo, "commit", "-q", "-m", "second commit") + + garbage := writeGarbageExternalDiff(t) + t.Setenv("GIT_EXTERNAL_DIFF", garbage) + + runner := gitcmd.New(0) + provider := NewCommitProvider(repo, "HEAD", runner) + + diffs, err := provider.GetDiff(context.Background()) + if err != nil { + t.Fatalf("GetDiff (commit) returned error: %v", err) + } + + if len(diffs) == 0 { + t.Fatalf("expected at least one parsed commit diff with an external diff "+ + "tool active, got 0 -- git show call site must pass "+ + "--no-ext-diff (issue #82). GIT_EXTERNAL_DIFF=%s", garbage) + } +} + // TestRangeDiffSurvivesExternalDiffTool covers the ModeRange call site // (git diff ), which likewise must pass --no-ext-diff so that a // user's external diff tool does not break range comparisons.