History

Git: Fix hunks being skipped when staging too quickly (#27552)

Release Notes: - Git: Fix hunks being skipped when staging too quickly. ---------

João Marcos committed 1 year ago

Commit 47b94e51 parent 29e2e132 files · +83 −53Browse files

Showing the changes to crates/buffer_diff/src/buffer_diff.rs (1 of 2 files). Show all

Unified · Split

crates/buffer_diff/src/buffer_diff.rs+34−44
@@ -187,13 +187,13 @@ impl BufferDiffSnapshot { · 186 unmodified lines
187187 impl BufferDiffInner {
188188 /// Returns the new index text and new pending hunks.
189189 fn stage_or_unstage_hunks_impl(
190− &self,
190+ &mut self,
191191 unstaged_diff: &Self,
192192 stage: bool,
193193 hunks: &[DiffHunk],
194194 buffer: &text::BufferSnapshot,
195195 file_exists: bool,
196− ) -> (Option<Rope>, SumTree<PendingHunk>) {
196+ ) -> Option<Rope> {
197197 let head_text = self
198198 .base_text_exists
199199 .then(|| self.base_text.as_rope().clone());
@@ -206,7 +206,7 @@ impl BufferDiffInner { · 6 unmodified lines
206206 let (index_text, head_text) = match (index_text, head_text) {
207207 (Some(index_text), Some(head_text)) if file_exists || !stage => (index_text, head_text),
208208 (index_text, head_text) => {
209− let (rope, new_status) = if stage {
209+ let (new_index_text, new_status) = if stage {
210210 log::debug!("stage all");
211211 (
212212 file_exists.then(|| buffer.as_rope().clone()),
@@ -226,15 +226,13 @@ impl BufferDiffInner { · 13 unmodified lines
226226 buffer_version: buffer.version().clone(),
227227 new_status,
228228 };
229− let tree = SumTree::from_item(hunk, buffer);
230− return (rope, tree);
229+ self.pending_hunks = SumTree::from_item(hunk, buffer);
230+ return new_index_text;
231231 }
232232 };
233233
234234 let mut pending_hunks = SumTree::new(buffer);
235− let mut old_pending_hunks = unstaged_diff
236− .pending_hunks
237− .cursor::<DiffHunkSummary>(buffer);
235+ let mut old_pending_hunks = self.pending_hunks.cursor::<DiffHunkSummary>(buffer);
238236
239237 // first, merge new hunks into pending_hunks
240238 for DiffHunk {
@@ -366,6 +364,8 @@ impl BufferDiffInner { · 125 unmodified lines
366364 edits.push((index_byte_range, replacement_text));
367365 }
368366 drop(pending_hunks_iter);
367+ drop(old_pending_hunks);
368+ self.pending_hunks = pending_hunks;
369369
370370 #[cfg(debug_assertions)] // invariants: non-overlapping and sorted
371371 {
@@ -384,7 +384,7 @@ impl BufferDiffInner { · 12 unmodified lines
384384 new_index_text.push(&replacement_text);
385385 }
386386 new_index_text.append(index_cursor.suffix());
387− (Some(new_index_text), pending_hunks)
387+ Some(new_index_text)
388388 }
389389
390390 fn hunks_intersecting_range<'a>(
@@ -421,15 +421,14 @@ impl BufferDiffInner { · 30 unmodified lines
421421 ]
422422 });
423423
424+ let mut pending_hunks_cursor = self.pending_hunks.cursor::<DiffHunkSummary>(buffer);
425+ pending_hunks_cursor.next(buffer);
426+
424427 let mut secondary_cursor = None;
425− let mut pending_hunks_cursor = None;
426428 if let Some(secondary) = secondary.as_ref() {
427429 let mut cursor = secondary.hunks.cursor::<DiffHunkSummary>(buffer);
428430 cursor.next(buffer);
429431 secondary_cursor = Some(cursor);
430− let mut cursor = secondary.pending_hunks.cursor::<DiffHunkSummary>(buffer);
431− cursor.next(buffer);
432− pending_hunks_cursor = Some(cursor);
433432 }
434433
435434 let max_point = buffer.max_point();
@@ -451,29 +450,27 @@ impl BufferDiffInner { · 15 unmodified lines
451450 let mut secondary_status = DiffHunkSecondaryStatus::NoSecondaryHunk;
452451
453452 let mut has_pending = false;
454− if let Some(pending_cursor) = pending_hunks_cursor.as_mut() {
455− if start_anchor
456− .cmp(&pending_cursor.start().buffer_range.start, buffer)
457− .is_gt()
458− {
459− pending_cursor.seek_forward(&start_anchor, Bias::Left, buffer);
460− }
453+ if start_anchor
454+ .cmp(&pending_hunks_cursor.start().buffer_range.start, buffer)
455+ .is_gt()
456+ {
457+ pending_hunks_cursor.seek_forward(&start_anchor, Bias::Left, buffer);
458+ }
461459
462− if let Some(pending_hunk) = pending_cursor.item() {
463− let mut pending_range = pending_hunk.buffer_range.to_point(buffer);
464− if pending_range.end.column > 0 {
465− pending_range.end.row += 1;
466− pending_range.end.column = 0;
467− }
460+ if let Some(pending_hunk) = pending_hunks_cursor.item() {
461+ let mut pending_range = pending_hunk.buffer_range.to_point(buffer);
462+ if pending_range.end.column > 0 {
463+ pending_range.end.row += 1;
464+ pending_range.end.column = 0;
465+ }
468466
469− if pending_range == (start_point..end_point) {
470− if !buffer.has_edits_since_in_range(
471− &pending_hunk.buffer_version,
472− start_anchor..end_anchor,
473− ) {
474− has_pending = true;
475− secondary_status = pending_hunk.new_status;
476− }
467+ if pending_range == (start_point..end_point) {
468+ if !buffer.has_edits_since_in_range(
469+ &pending_hunk.buffer_version,
470+ start_anchor..end_anchor,
471+ ) {
472+ has_pending = true;
473+ secondary_status = pending_hunk.new_status;
477474 }
478475 }
479476 }
@@ -852,10 +849,8 @@ impl BufferDiff { · 372 unmodified lines
852849 }
853850
854851 pub fn clear_pending_hunks(&mut self, cx: &mut Context<Self>) {
855− if let Some(secondary_diff) = &self.secondary_diff {
856− secondary_diff.update(cx, |diff, _| {
857− diff.inner.pending_hunks = SumTree::from_summary(DiffHunkSummary::default());
858− });
852+ if self.secondary_diff.is_some() {
853+ self.inner.pending_hunks = SumTree::from_summary(DiffHunkSummary::default());
859854 cx.emit(BufferDiffEvent::DiffChanged {
860855 changed_range: Some(Anchor::MIN..Anchor::MAX),
861856 });
@@ -870,7 +865,7 @@ impl BufferDiff { · 8 unmodified lines
870865 file_exists: bool,
871866 cx: &mut Context<Self>,
872867 ) -> Option<Rope> {
873− let (new_index_text, new_pending_hunks) = self.inner.stage_or_unstage_hunks_impl(
868+ let new_index_text = self.inner.stage_or_unstage_hunks_impl(
874869 &self.secondary_diff.as_ref()?.read(cx).inner,
875870 stage,
876871 &hunks,
@@ -878,11 +873,6 @@ impl BufferDiff { · 1 unmodified line
878873 file_exists,
879874 );
880875
881− if let Some(unstaged_diff) = &self.secondary_diff {
882− unstaged_diff.update(cx, |diff, _| {
883− diff.inner.pending_hunks = new_pending_hunks;
884− });
885− }
886876 cx.emit(BufferDiffEvent::HunksStagedOrUnstaged(
887877 new_index_text.clone(),
888878 ));