Release Notes: - Git: Fix hunks being skipped when staging too quickly. ---------
Showing the changes to crates/buffer_diff/src/buffer_diff.rs (1 of 2 files). Show all
Unified · Split
| @@ -187,13 +187,13 @@ impl BufferDiffSnapshot { · 186 unmodified lines | ||
| 187 | 187 | impl BufferDiffInner { |
| 188 | 188 | /// Returns the new index text and new pending hunks. |
| 189 | 189 | fn stage_or_unstage_hunks_impl( |
| 190 | − &self, | |
| 190 | + &mut self, | |
| 191 | 191 | unstaged_diff: &Self, |
| 192 | 192 | stage: bool, |
| 193 | 193 | hunks: &[DiffHunk], |
| 194 | 194 | buffer: &text::BufferSnapshot, |
| 195 | 195 | file_exists: bool, |
| 196 | − ) -> (Option<Rope>, SumTree<PendingHunk>) { | |
| 196 | + ) -> Option<Rope> { | |
| 197 | 197 | let head_text = self |
| 198 | 198 | .base_text_exists |
| 199 | 199 | .then(|| self.base_text.as_rope().clone()); |
| @@ -206,7 +206,7 @@ impl BufferDiffInner { · 6 unmodified lines | ||
| 206 | 206 | let (index_text, head_text) = match (index_text, head_text) { |
| 207 | 207 | (Some(index_text), Some(head_text)) if file_exists || !stage => (index_text, head_text), |
| 208 | 208 | (index_text, head_text) => { |
| 209 | − let (rope, new_status) = if stage { | |
| 209 | + let (new_index_text, new_status) = if stage { | |
| 210 | 210 | log::debug!("stage all"); |
| 211 | 211 | ( |
| 212 | 212 | file_exists.then(|| buffer.as_rope().clone()), |
| @@ -226,15 +226,13 @@ impl BufferDiffInner { · 13 unmodified lines | ||
| 226 | 226 | buffer_version: buffer.version().clone(), |
| 227 | 227 | new_status, |
| 228 | 228 | }; |
| 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; | |
| 231 | 231 | } |
| 232 | 232 | }; |
| 233 | 233 | |
| 234 | 234 | 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); | |
| 238 | 236 | |
| 239 | 237 | // first, merge new hunks into pending_hunks |
| 240 | 238 | for DiffHunk { |
| @@ -366,6 +364,8 @@ impl BufferDiffInner { · 125 unmodified lines | ||
| 366 | 364 | edits.push((index_byte_range, replacement_text)); |
| 367 | 365 | } |
| 368 | 366 | drop(pending_hunks_iter); |
| 367 | + drop(old_pending_hunks); | |
| 368 | + self.pending_hunks = pending_hunks; | |
| 369 | 369 | |
| 370 | 370 | #[cfg(debug_assertions)] // invariants: non-overlapping and sorted |
| 371 | 371 | { |
| @@ -384,7 +384,7 @@ impl BufferDiffInner { · 12 unmodified lines | ||
| 384 | 384 | new_index_text.push(&replacement_text); |
| 385 | 385 | } |
| 386 | 386 | new_index_text.append(index_cursor.suffix()); |
| 387 | − (Some(new_index_text), pending_hunks) | |
| 387 | + Some(new_index_text) | |
| 388 | 388 | } |
| 389 | 389 | |
| 390 | 390 | fn hunks_intersecting_range<'a>( |
| @@ -421,15 +421,14 @@ impl BufferDiffInner { · 30 unmodified lines | ||
| 421 | 421 | ] |
| 422 | 422 | }); |
| 423 | 423 | |
| 424 | + let mut pending_hunks_cursor = self.pending_hunks.cursor::<DiffHunkSummary>(buffer); | |
| 425 | + pending_hunks_cursor.next(buffer); | |
| 426 | + | |
| 424 | 427 | let mut secondary_cursor = None; |
| 425 | − let mut pending_hunks_cursor = None; | |
| 426 | 428 | if let Some(secondary) = secondary.as_ref() { |
| 427 | 429 | let mut cursor = secondary.hunks.cursor::<DiffHunkSummary>(buffer); |
| 428 | 430 | cursor.next(buffer); |
| 429 | 431 | secondary_cursor = Some(cursor); |
| 430 | − let mut cursor = secondary.pending_hunks.cursor::<DiffHunkSummary>(buffer); | |
| 431 | − cursor.next(buffer); | |
| 432 | − pending_hunks_cursor = Some(cursor); | |
| 433 | 432 | } |
| 434 | 433 | |
| 435 | 434 | let max_point = buffer.max_point(); |
| @@ -451,29 +450,27 @@ impl BufferDiffInner { · 15 unmodified lines | ||
| 451 | 450 | let mut secondary_status = DiffHunkSecondaryStatus::NoSecondaryHunk; |
| 452 | 451 | |
| 453 | 452 | 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 | + } | |
| 461 | 459 | |
| 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 | + } | |
| 468 | 466 | |
| 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; | |
| 477 | 474 | } |
| 478 | 475 | } |
| 479 | 476 | } |
| @@ -852,10 +849,8 @@ impl BufferDiff { · 372 unmodified lines | ||
| 852 | 849 | } |
| 853 | 850 | |
| 854 | 851 | 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()); | |
| 859 | 854 | cx.emit(BufferDiffEvent::DiffChanged { |
| 860 | 855 | changed_range: Some(Anchor::MIN..Anchor::MAX), |
| 861 | 856 | }); |
| @@ -870,7 +865,7 @@ impl BufferDiff { · 8 unmodified lines | ||
| 870 | 865 | file_exists: bool, |
| 871 | 866 | cx: &mut Context<Self>, |
| 872 | 867 | ) -> 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( | |
| 874 | 869 | &self.secondary_diff.as_ref()?.read(cx).inner, |
| 875 | 870 | stage, |
| 876 | 871 | &hunks, |
| @@ -878,11 +873,6 @@ impl BufferDiff { · 1 unmodified line | ||
| 878 | 873 | file_exists, |
| 879 | 874 | ); |
| 880 | 875 | |
| 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 | − } | |
| 886 | 876 | cx.emit(BufferDiffEvent::HunksStagedOrUnstaged( |
| 887 | 877 | new_index_text.clone(), |
| 888 | 878 | )); |