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 | impl BufferDiffInner { | 187 | impl BufferDiffInner { |
| 188 | /// Returns the new index text and new pending hunks. | 188 | /// Returns the new index text and new pending hunks. |
| 189 | fn stage_or_unstage_hunks_impl( | 189 | fn stage_or_unstage_hunks_impl( |
| 190 | &self, | 190 | &mut self, |
| 191 | unstaged_diff: &Self, | 191 | unstaged_diff: &Self, |
| 192 | stage: bool, | 192 | stage: bool, |
| 193 | hunks: &[DiffHunk], | 193 | hunks: &[DiffHunk], |
| 194 | buffer: &text::BufferSnapshot, | 194 | buffer: &text::BufferSnapshot, |
| 195 | file_exists: bool, | 195 | file_exists: bool, |
| 196 | ) -> (Option<Rope>, SumTree<PendingHunk>) { | 196 | ) -> Option<Rope> { |
| 197 | let head_text = self | 197 | let head_text = self |
| 198 | .base_text_exists | 198 | .base_text_exists |
| 199 | .then(|| self.base_text.as_rope().clone()); | 199 | .then(|| self.base_text.as_rope().clone()); |
| @@ -206,7 +206,7 @@ impl BufferDiffInner { · 6 unmodified lines | |||
| 206 | let (index_text, head_text) = match (index_text, head_text) { | 206 | let (index_text, head_text) = match (index_text, head_text) { |
| 207 | (Some(index_text), Some(head_text)) if file_exists || !stage => (index_text, head_text), | 207 | (Some(index_text), Some(head_text)) if file_exists || !stage => (index_text, head_text), |
| 208 | (index_text, head_text) => { | 208 | (index_text, head_text) => { |
| 209 | let (rope, new_status) = if stage { | 209 | let (new_index_text, new_status) = if stage { |
| 210 | log::debug!("stage all"); | 210 | log::debug!("stage all"); |
| 211 | ( | 211 | ( |
| 212 | file_exists.then(|| buffer.as_rope().clone()), | 212 | file_exists.then(|| buffer.as_rope().clone()), |
| @@ -226,15 +226,13 @@ impl BufferDiffInner { · 13 unmodified lines | |||
| 226 | buffer_version: buffer.version().clone(), | 226 | buffer_version: buffer.version().clone(), |
| 227 | new_status, | 227 | new_status, |
| 228 | }; | 228 | }; |
| 229 | let tree = SumTree::from_item(hunk, buffer); | 229 | self.pending_hunks = SumTree::from_item(hunk, buffer); |
| 230 | return (rope, tree); | 230 | return new_index_text; |
| 231 | } | 231 | } |
| 232 | }; | 232 | }; |
| 233 | 233 | ||
| 234 | let mut pending_hunks = SumTree::new(buffer); | 234 | let mut pending_hunks = SumTree::new(buffer); |
| 235 | let mut old_pending_hunks = unstaged_diff | 235 | let mut old_pending_hunks = self.pending_hunks.cursor::<DiffHunkSummary>(buffer); |
| 236 | .pending_hunks | ||
| 237 | .cursor::<DiffHunkSummary>(buffer); | ||
| 238 | 236 | ||
| 239 | // first, merge new hunks into pending_hunks | 237 | // first, merge new hunks into pending_hunks |
| 240 | for DiffHunk { | 238 | for DiffHunk { |
| @@ -366,6 +364,8 @@ impl BufferDiffInner { · 125 unmodified lines | |||
| 366 | edits.push((index_byte_range, replacement_text)); | 364 | edits.push((index_byte_range, replacement_text)); |
| 367 | } | 365 | } |
| 368 | drop(pending_hunks_iter); | 366 | drop(pending_hunks_iter); |
| 367 | drop(old_pending_hunks); | ||
| 368 | self.pending_hunks = pending_hunks; | ||
| 369 | 369 | ||
| 370 | #[cfg(debug_assertions)] // invariants: non-overlapping and sorted | 370 | #[cfg(debug_assertions)] // invariants: non-overlapping and sorted |
| 371 | { | 371 | { |
| @@ -384,7 +384,7 @@ impl BufferDiffInner { · 12 unmodified lines | |||
| 384 | new_index_text.push(&replacement_text); | 384 | new_index_text.push(&replacement_text); |
| 385 | } | 385 | } |
| 386 | new_index_text.append(index_cursor.suffix()); | 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 | fn hunks_intersecting_range<'a>( | 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 | let mut secondary_cursor = None; | 427 | let mut secondary_cursor = None; |
| 425 | let mut pending_hunks_cursor = None; | ||
| 426 | if let Some(secondary) = secondary.as_ref() { | 428 | if let Some(secondary) = secondary.as_ref() { |
| 427 | let mut cursor = secondary.hunks.cursor::<DiffHunkSummary>(buffer); | 429 | let mut cursor = secondary.hunks.cursor::<DiffHunkSummary>(buffer); |
| 428 | cursor.next(buffer); | 430 | cursor.next(buffer); |
| 429 | secondary_cursor = Some(cursor); | 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 | let max_point = buffer.max_point(); | 434 | let max_point = buffer.max_point(); |
| @@ -451,29 +450,27 @@ impl BufferDiffInner { · 15 unmodified lines | |||
| 451 | let mut secondary_status = DiffHunkSecondaryStatus::NoSecondaryHunk; | 450 | let mut secondary_status = DiffHunkSecondaryStatus::NoSecondaryHunk; |
| 452 | 451 | ||
| 453 | let mut has_pending = false; | 452 | let mut has_pending = false; |
| 454 | if let Some(pending_cursor) = pending_hunks_cursor.as_mut() { | 453 | if start_anchor |
| 455 | if start_anchor | 454 | .cmp(&pending_hunks_cursor.start().buffer_range.start, buffer) |
| 456 | .cmp(&pending_cursor.start().buffer_range.start, buffer) | 455 | .is_gt() |
| 457 | .is_gt() | 456 | { |
| 458 | { | 457 | pending_hunks_cursor.seek_forward(&start_anchor, Bias::Left, buffer); |
| 459 | pending_cursor.seek_forward(&start_anchor, Bias::Left, buffer); | 458 | } |
| 460 | } | ||
| 461 | 459 | ||
| 462 | if let Some(pending_hunk) = pending_cursor.item() { | 460 | if let Some(pending_hunk) = pending_hunks_cursor.item() { |
| 463 | let mut pending_range = pending_hunk.buffer_range.to_point(buffer); | 461 | let mut pending_range = pending_hunk.buffer_range.to_point(buffer); |
| 464 | if pending_range.end.column > 0 { | 462 | if pending_range.end.column > 0 { |
| 465 | pending_range.end.row += 1; | 463 | pending_range.end.row += 1; |
| 466 | pending_range.end.column = 0; | 464 | pending_range.end.column = 0; |
| 467 | } | 465 | } |
| 468 | 466 | ||
| 469 | if pending_range == (start_point..end_point) { | 467 | if pending_range == (start_point..end_point) { |
| 470 | if !buffer.has_edits_since_in_range( | 468 | if !buffer.has_edits_since_in_range( |
| 471 | &pending_hunk.buffer_version, | 469 | &pending_hunk.buffer_version, |
| 472 | start_anchor..end_anchor, | 470 | start_anchor..end_anchor, |
| 473 | ) { | 471 | ) { |
| 474 | has_pending = true; | 472 | has_pending = true; |
| 475 | secondary_status = pending_hunk.new_status; | 473 | secondary_status = pending_hunk.new_status; |
| 476 | } | ||
| 477 | } | 474 | } |
| 478 | } | 475 | } |
| 479 | } | 476 | } |
| @@ -852,10 +849,8 @@ impl BufferDiff { · 372 unmodified lines | |||
| 852 | } | 849 | } |
| 853 | 850 | ||
| 854 | pub fn clear_pending_hunks(&mut self, cx: &mut Context<Self>) { | 851 | pub fn clear_pending_hunks(&mut self, cx: &mut Context<Self>) { |
| 855 | if let Some(secondary_diff) = &self.secondary_diff { | 852 | if self.secondary_diff.is_some() { |
| 856 | secondary_diff.update(cx, |diff, _| { | 853 | self.inner.pending_hunks = SumTree::from_summary(DiffHunkSummary::default()); |
| 857 | diff.inner.pending_hunks = SumTree::from_summary(DiffHunkSummary::default()); | ||
| 858 | }); | ||
| 859 | cx.emit(BufferDiffEvent::DiffChanged { | 854 | cx.emit(BufferDiffEvent::DiffChanged { |
| 860 | changed_range: Some(Anchor::MIN..Anchor::MAX), | 855 | changed_range: Some(Anchor::MIN..Anchor::MAX), |
| 861 | }); | 856 | }); |
| @@ -870,7 +865,7 @@ impl BufferDiff { · 8 unmodified lines | |||
| 870 | file_exists: bool, | 865 | file_exists: bool, |
| 871 | cx: &mut Context<Self>, | 866 | cx: &mut Context<Self>, |
| 872 | ) -> Option<Rope> { | 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 | &self.secondary_diff.as_ref()?.read(cx).inner, | 869 | &self.secondary_diff.as_ref()?.read(cx).inner, |
| 875 | stage, | 870 | stage, |
| 876 | &hunks, | 871 | &hunks, |
| @@ -878,11 +873,6 @@ impl BufferDiff { · 1 unmodified line | |||
| 878 | file_exists, | 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 | cx.emit(BufferDiffEvent::HunksStagedOrUnstaged( | 876 | cx.emit(BufferDiffEvent::HunksStagedOrUnstaged( |
| 887 | new_index_text.clone(), | 877 | new_index_text.clone(), |
| 888 | )); | 878 | )); |