|
1 | | -use std::{num::NonZeroU32, ops::Range}; |
| 1 | +use std::num::NonZeroU32; |
2 | 2 |
|
3 | | -use gix_diff::{blob::intern::TokenSource, tree::Visit}; |
| 3 | +use gix_diff::{ |
| 4 | + blob::{intern::TokenSource, v2::Hunk}, |
| 5 | + tree::Visit, |
| 6 | +}; |
4 | 7 | use gix_hash::ObjectId; |
5 | 8 | use gix_object::{ |
6 | 9 | bstr::{BStr, BString}, |
@@ -758,85 +761,65 @@ fn blob_changes( |
758 | 761 | diff_algorithm: gix_diff::blob::Algorithm, |
759 | 762 | stats: &mut Statistics, |
760 | 763 | ) -> Result<Vec<Change>, Error> { |
761 | | - /// Record all [`Change`]s to learn about additions, deletions and unchanged portions of a *Source File*. |
762 | | - struct ChangeRecorder { |
763 | | - last_seen_after_end: u32, |
764 | | - hunks: Vec<Change>, |
765 | | - total_number_of_lines: u32, |
766 | | - } |
| 764 | + resource_cache.set_resource( |
| 765 | + previous_oid, |
| 766 | + gix_object::tree::EntryKind::Blob, |
| 767 | + previous_file_path, |
| 768 | + gix_diff::blob::ResourceKind::OldOrSource, |
| 769 | + &odb, |
| 770 | + )?; |
| 771 | + resource_cache.set_resource( |
| 772 | + oid, |
| 773 | + gix_object::tree::EntryKind::Blob, |
| 774 | + file_path, |
| 775 | + gix_diff::blob::ResourceKind::NewOrDestination, |
| 776 | + &odb, |
| 777 | + )?; |
767 | 778 |
|
768 | | - impl ChangeRecorder { |
769 | | - /// `total_number_of_lines` is used to fill in the last unchanged hunk if needed |
770 | | - /// so that the entire file is represented by [`Change`]. |
771 | | - fn new(total_number_of_lines: u32) -> Self { |
772 | | - ChangeRecorder { |
773 | | - last_seen_after_end: 0, |
774 | | - hunks: Vec::new(), |
775 | | - total_number_of_lines, |
776 | | - } |
777 | | - } |
778 | | - } |
| 779 | + let outcome = resource_cache.prepare_diff()?; |
| 780 | + let input = gix_diff::blob::v2::InternedInput::new( |
| 781 | + outcome.old.data.as_slice().unwrap_or_default(), |
| 782 | + outcome.new.data.as_slice().unwrap_or_default(), |
| 783 | + ); |
| 784 | + |
| 785 | + let diff_algorithm: gix_diff::blob::v2::Algorithm = match diff_algorithm { |
| 786 | + gix_diff::blob::Algorithm::Histogram => gix_diff::blob::v2::Algorithm::Histogram, |
| 787 | + gix_diff::blob::Algorithm::Myers => gix_diff::blob::v2::Algorithm::Myers, |
| 788 | + gix_diff::blob::Algorithm::MyersMinimal => gix_diff::blob::v2::Algorithm::MyersMinimal, |
| 789 | + }; |
| 790 | + let mut diff = gix_diff::blob::v2::Diff::compute(diff_algorithm, &input); |
| 791 | + diff.postprocess_lines(&input); |
779 | 792 |
|
780 | | - impl gix_diff::blob::Sink for ChangeRecorder { |
781 | | - type Out = Vec<Change>; |
| 793 | + let changes = diff |
| 794 | + .hunks() |
| 795 | + .fold((Vec::new(), 0), |(mut hunks, mut last_seen_after_end), hunk| { |
| 796 | + let Hunk { before, after } = hunk; |
782 | 797 |
|
783 | | - fn process_change(&mut self, before: Range<u32>, after: Range<u32>) { |
784 | 798 | // This checks for unchanged hunks. |
785 | | - if after.start > self.last_seen_after_end { |
786 | | - self.hunks |
787 | | - .push(Change::Unchanged(self.last_seen_after_end..after.start)); |
| 799 | + if after.start > last_seen_after_end { |
| 800 | + hunks.push(Change::Unchanged(last_seen_after_end..after.start)); |
788 | 801 | } |
789 | 802 |
|
790 | 803 | match (!before.is_empty(), !after.is_empty()) { |
791 | 804 | (_, true) => { |
792 | | - self.hunks.push(Change::AddedOrReplaced( |
| 805 | + hunks.push(Change::AddedOrReplaced( |
793 | 806 | after.start..after.end, |
794 | 807 | before.end - before.start, |
795 | 808 | )); |
796 | 809 | } |
797 | 810 | (true, false) => { |
798 | | - self.hunks.push(Change::Deleted(after.start, before.end - before.start)); |
| 811 | + hunks.push(Change::Deleted(after.start, before.end - before.start)); |
799 | 812 | } |
800 | 813 | (false, false) => unreachable!("BUG: imara-diff provided a non-change"), |
801 | 814 | } |
802 | | - self.last_seen_after_end = after.end; |
803 | | - } |
804 | | - |
805 | | - fn finish(mut self) -> Self::Out { |
806 | | - if self.total_number_of_lines > self.last_seen_after_end { |
807 | | - self.hunks |
808 | | - .push(Change::Unchanged(self.last_seen_after_end..self.total_number_of_lines)); |
809 | | - } |
810 | | - self.hunks |
811 | | - } |
812 | | - } |
813 | 815 |
|
814 | | - resource_cache.set_resource( |
815 | | - previous_oid, |
816 | | - gix_object::tree::EntryKind::Blob, |
817 | | - previous_file_path, |
818 | | - gix_diff::blob::ResourceKind::OldOrSource, |
819 | | - &odb, |
820 | | - )?; |
821 | | - resource_cache.set_resource( |
822 | | - oid, |
823 | | - gix_object::tree::EntryKind::Blob, |
824 | | - file_path, |
825 | | - gix_diff::blob::ResourceKind::NewOrDestination, |
826 | | - &odb, |
827 | | - )?; |
| 816 | + last_seen_after_end = after.end; |
828 | 817 |
|
829 | | - let outcome = resource_cache.prepare_diff()?; |
830 | | - let input = gix_diff::blob::intern::InternedInput::new( |
831 | | - tokens_for_diffing(outcome.old.data.as_slice().unwrap_or_default()), |
832 | | - tokens_for_diffing(outcome.new.data.as_slice().unwrap_or_default()), |
833 | | - ); |
834 | | - let number_of_lines_in_destination = input.after.len(); |
835 | | - let change_recorder = ChangeRecorder::new(number_of_lines_in_destination as u32); |
| 818 | + (hunks, last_seen_after_end) |
| 819 | + }); |
836 | 820 |
|
837 | | - let res = gix_diff::blob::diff(diff_algorithm, &input, change_recorder); |
838 | 821 | stats.blobs_diffed += 1; |
839 | | - Ok(res) |
| 822 | + Ok(changes.0) |
840 | 823 | } |
841 | 824 |
|
842 | 825 | fn find_path_entry_in_commit( |
|
0 commit comments