Skip to content

Commit 01be2e1

Browse files
geevensinghCopilot
andcommitted
DiffViewer: show only changed lines in revert-hunk preview
The "Revert hunk?" confirmation dialog built its 3-line preview by taking the first 3 lines of the hunk - which, because DiffService prepends 3 lines of unchanged context to every hunk, almost always meant the user saw three lines that weren't even being reverted, and nothing about the actual change. Filter the preview to inserted/deleted/modified lines only and prefix each with the standard diff marker (+/-/~) so the user can see what will actually be discarded. The overflow indicator (...) now counts overflow among changed lines rather than total lines, matching what the user is now reading. Adds a regression test asserting the preview contains the changed lines with markers and not the leading context line. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 7fc48c7 commit 01be2e1

2 files changed

Lines changed: 60 additions & 3 deletions

File tree

DiffViewer.Tests/ViewModels/MainViewModelContextMenuTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,42 @@ await RunOnUiSyncContextAsync(async vm =>
336336
settings.Current.SuppressRevertHunkConfirmation.Should().BeTrue();
337337
}
338338

339+
[Fact]
340+
public async Task RevertHunkAtCaret_PreviewShowsOnlyChangedLinesWithMarkers()
341+
{
342+
// Repro of the "useless preview" bug: leading context lines were
343+
// taking up the entire 3-line preview window, so the user saw three
344+
// unchanged lines and zero indication of what was about to be
345+
// discarded. The fix filters out Context lines and prefixes diff
346+
// markers so the preview actually previews the revert.
347+
var repo = new FakeRepositoryService(_repoRoot)
348+
{
349+
LeftText = "alpha\nbeta\n",
350+
RightText = "alpha\ngamma\n",
351+
};
352+
var git = new FakeGitWriteService();
353+
ConfirmationRequest? seen = null;
354+
355+
await RunOnUiSyncContextAsync(async vm =>
356+
{
357+
vm.ConfirmHandler = req =>
358+
{
359+
seen = req;
360+
return ConfirmationResult.Cancel();
361+
};
362+
await vm.DiffPane.LoadAsync(ModifiedRow("a.cs"));
363+
var hunk = vm.DiffPane.CurrentHunks.First();
364+
vm.RevertHunkAtCaretCommand.Execute(
365+
new HunkActionContext(ChangeSide.Right, hunk.NewStartLine));
366+
}, repo, git);
367+
368+
seen.Should().NotBeNull();
369+
seen!.Message.Should().Contain("- beta", "deleted line should appear in preview with '-' marker");
370+
seen.Message.Should().Contain("+ gamma", "inserted line should appear in preview with '+' marker");
371+
seen.Message.Should().NotContain("Preview:\nalpha",
372+
"leading context line should be filtered out of preview");
373+
}
374+
339375
[Fact]
340376
public async Task RevertHunkAtCaret_WhenSuppressionOn_SkipsPrompt()
341377
{

DiffViewer/ViewModels/MainViewModel.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,33 @@ private async Task RevertHunkAtCaret(HunkActionContext? ctx)
213213
var suppress = _settingsService?.Current.SuppressRevertHunkConfirmation ?? false;
214214
if (!suppress)
215215
{
216-
var preview = inputs.Hunk.Lines.Take(3).Select(l => l.Text).ToArray();
216+
// Preview the lines that will actually be reverted: filter to
217+
// inserted/deleted/modified (skip context, which is unchanged
218+
// and tells the user nothing about what's being discarded) and
219+
// prefix each with the standard diff marker so + / - reads
220+
// naturally. The earlier "first 3 lines of the hunk" approach
221+
// surfaced only the leading context lines that DiffService adds
222+
// around every hunk, so the dialog showed three unchanged
223+
// lines and no actual changes - useless for confirming intent.
224+
var changedLines = inputs.Hunk.Lines
225+
.Where(l => l.Kind is DiffLineKind.Inserted
226+
or DiffLineKind.Deleted
227+
or DiffLineKind.Modified)
228+
.ToList();
229+
var previewLines = changedLines
230+
.Take(3)
231+
.Select(l => (l.Kind switch
232+
{
233+
DiffLineKind.Inserted => "+ ",
234+
DiffLineKind.Deleted => "- ",
235+
DiffLineKind.Modified => "~ ",
236+
_ => " ",
237+
}) + l.Text);
217238
var resp = ConfirmHandler?.Invoke(new ConfirmationRequest(
218239
Title: "Revert hunk?",
219240
Message: "Discard this hunk from the working tree? This cannot be undone via git.\n\n"
220-
+ "Preview:\n" + string.Join("\n", preview)
221-
+ (inputs.Hunk.Lines.Count > 3 ? "\n…" : ""),
241+
+ "Preview:\n" + string.Join("\n", previewLines)
242+
+ (changedLines.Count > 3 ? "\n…" : ""),
222243
ConfirmText: "Revert",
223244
CancelText: "Cancel",
224245
ShowDontAskAgain: true));

0 commit comments

Comments
 (0)