What's wrong
GitDiffBuilder (GitIntegration/Builders/GitDiffBuilder.cs ~L172-180) adds --find-renames / --find-copies only when requested and never passes --no-renames. Git has defaulted diff.renames=true since 2.9, so rename detection is effectively always on, and its behavior depends on the host's config. GitPatchBuilder already pins this (arguments.Add(_detectRenames ? "--find-renames" : "--no-renames"), the #121 fix), so the two builders now disagree.
Failure scenario (reproduced with a library-level test)
- Commit
old.txt, then git mv old.txt new.txt.
repo.Diff().Staged() — no DetectRenames() — returns Renamed old.txt -> new.txt.
repo.Patch().Staged() returns Added new.txt; Deleted old.txt.
Consequences:
DetectRenames() is a no-op in a default git setup; callers cannot turn rename detection off.
- A staging UI that takes its file list from
Diff() and hunks from Patch() can't match entries up.
- Results vary by host:
diff.renames=false turns renames off; diff.renames=copies emits copy (C) entries without DetectCopies().
Suggested fix
Always set rename detection explicitly, mirroring GitPatchBuilder: emit --find-copies if _detectCopies, else --find-renames if _detectRenames, else --no-renames. Update the DetectRenames()/DetectCopies() XML docs to state detection is off unless requested, regardless of diff.renames (matching IGitPatchBuilder.DetectRenames).
Acceptance criteria
Diff().Staged() without DetectRenames() reports Added + Deleted for a git mv, matching Patch().
- With
DetectRenames() it reports Renamed.
- Tests run with
diff.renames set to true, false and copies in the repo config and produce identical results.
What's wrong
GitDiffBuilder(GitIntegration/Builders/GitDiffBuilder.cs~L172-180) adds--find-renames/--find-copiesonly when requested and never passes--no-renames. Git has defaulteddiff.renames=truesince 2.9, so rename detection is effectively always on, and its behavior depends on the host's config.GitPatchBuilderalready pins this (arguments.Add(_detectRenames ? "--find-renames" : "--no-renames"), the #121 fix), so the two builders now disagree.Failure scenario (reproduced with a library-level test)
old.txt, thengit mv old.txt new.txt.repo.Diff().Staged()— noDetectRenames()— returnsRenamed old.txt -> new.txt.repo.Patch().Staged()returnsAdded new.txt; Deleted old.txt.Consequences:
DetectRenames()is a no-op in a default git setup; callers cannot turn rename detection off.Diff()and hunks fromPatch()can't match entries up.diff.renames=falseturns renames off;diff.renames=copiesemits copy (C) entries withoutDetectCopies().Suggested fix
Always set rename detection explicitly, mirroring
GitPatchBuilder: emit--find-copiesif_detectCopies, else--find-renamesif_detectRenames, else--no-renames. Update theDetectRenames()/DetectCopies()XML docs to state detection is off unless requested, regardless ofdiff.renames(matchingIGitPatchBuilder.DetectRenames).Acceptance criteria
Diff().Staged()withoutDetectRenames()reports Added + Deleted for agit mv, matchingPatch().DetectRenames()it reports Renamed.diff.renamesset totrue,falseandcopiesin the repo config and produce identical results.