From ad24b3f0a0a71ce0cb324a235c1f050205a2fa6b Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Thu, 29 Jan 2026 11:48:40 -0500 Subject: [PATCH] git: Fix missing hunk controls on side-by-side diff RHS (#47815) Release Notes: - N/A --- crates/editor/src/element.rs | 7 ---- crates/multi_buffer/src/multi_buffer.rs | 14 ++++++- crates/multi_buffer/src/multi_buffer_tests.rs | 41 +++++++++++++++++++ 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index f022a0064b8a92a3bb97ec08df04b33767c2b8c4..cd626cdb33389b748ad31928c1080de736a3dd53 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -5567,13 +5567,6 @@ impl EditorElement { if row_infos[row_ix].diff_status.is_none() { continue; } - if row_infos[row_ix] - .diff_status - .is_some_and(|status| status.is_added()) - && !status.is_added() - { - continue; - } if active_positions .iter() diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index deb92538253768d5cfb70ae969c6dab7f09122f2..31fc72ad2bbd6e432f3ad016c2c0ba0f3fec4dd3 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -4141,6 +4141,14 @@ impl MultiBufferSnapshot { && region.range.start > MBD::default() { cursor.prev() + } else if let Some(region) = cursor.region() + && region.is_main_buffer + && region.diff_hunk_status.is_some() + { + cursor.prev(); + if cursor.region().is_none_or(|region| region.is_main_buffer) { + cursor.next(); + } } iter::from_fn(move || { @@ -4193,9 +4201,11 @@ impl MultiBufferSnapshot { // the metadata item's range. if metadata_buffer_range.start > ::default() { while let Some(region) = cursor.region() { - if region.is_main_buffer + if (region.is_main_buffer && (region.buffer_range.end >= metadata_buffer_range.start - || cursor.is_at_end_of_excerpt()) + || cursor.is_at_end_of_excerpt())) + || (!region.is_main_buffer + && region.buffer_range.start == metadata_buffer_range.start) { break; } diff --git a/crates/multi_buffer/src/multi_buffer_tests.rs b/crates/multi_buffer/src/multi_buffer_tests.rs index 0ab14a2739257d72b1882ceb38466f7886ac1c46..8792f95e39c966fbc0af08db33cd692ed6fe5c37 100644 --- a/crates/multi_buffer/src/multi_buffer_tests.rs +++ b/crates/multi_buffer/src/multi_buffer_tests.rs @@ -473,6 +473,47 @@ async fn test_diff_hunks_in_range(cx: &mut TestAppContext) { ); } +#[gpui::test] +async fn test_diff_hunks_in_range_query_starting_at_added_row(cx: &mut TestAppContext) { + let base_text = "one\ntwo\nthree\n"; + let text = "one\nTWO\nthree\n"; + let buffer = cx.new(|cx| Buffer::local(text, cx)); + let diff = cx + .new(|cx| BufferDiff::new_with_base_text(base_text, &buffer.read(cx).text_snapshot(), cx)); + let multibuffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx)); + let (mut snapshot, mut subscription) = multibuffer.update(cx, |multibuffer, cx| { + (multibuffer.snapshot(cx), multibuffer.subscribe()) + }); + + multibuffer.update(cx, |multibuffer, cx| { + multibuffer.add_diff(diff, cx); + multibuffer.expand_diff_hunks(vec![Anchor::min()..Anchor::max()], cx); + }); + + assert_new_snapshot( + &multibuffer, + &mut snapshot, + &mut subscription, + cx, + indoc! { + " one + - two + + TWO + three + " + }, + ); + + assert_eq!( + snapshot + .diff_hunks_in_range(Point::new(2, 0)..Point::MAX) + .map(|hunk| hunk.row_range.start.0..hunk.row_range.end.0) + .collect::>(), + vec![1..3], + "querying starting at the added row should still return the full hunk including deleted lines" + ); +} + #[gpui::test] async fn test_inverted_diff_hunks_in_range(cx: &mut TestAppContext) { let base_text = "one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\n";