Skip to content

Commit 2c88262

Browse files
committed
Update gix-blame to imara-diff 0.2
1 parent 111b625 commit 2c88262

File tree

3 files changed

+48
-64
lines changed

3 files changed

+48
-64
lines changed

gix-blame/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ gix-commitgraph = { version = "^0.30.0", path = "../gix-commitgraph" }
1515
gix-revwalk = { version = "^0.23.0", path = "../gix-revwalk" }
1616
gix-trace = { version = "^0.1.14", path = "../gix-trace" }
1717
gix-date = { version = "^0.11.0", path = "../gix-date" }
18-
gix-diff = { version = "^0.55.0", path = "../gix-diff", default-features = false, features = ["blob"] }
18+
gix-diff = { version = "^0.55.0", path = "../gix-diff", default-features = false, features = ["blob", "blob-experimental"] }
1919
gix-object = { version = "^0.52.0", path = "../gix-object" }
2020
gix-hash = { version = "^0.20.0", path = "../gix-hash" }
2121
gix-worktree = { version = "^0.44.0", path = "../gix-worktree", default-features = false, features = ["attributes"] }

gix-blame/src/file/function.rs

Lines changed: 44 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
use std::{num::NonZeroU32, ops::Range};
1+
use std::num::NonZeroU32;
22

3-
use gix_diff::{blob::intern::TokenSource, tree::Visit};
3+
use gix_diff::{
4+
blob::{intern::TokenSource, v2::Hunk},
5+
tree::Visit,
6+
};
47
use gix_hash::ObjectId;
58
use gix_object::{
69
bstr::{BStr, BString},
@@ -758,85 +761,65 @@ fn blob_changes(
758761
diff_algorithm: gix_diff::blob::Algorithm,
759762
stats: &mut Statistics,
760763
) -> 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+
)?;
767778

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);
779792

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;
782797

783-
fn process_change(&mut self, before: Range<u32>, after: Range<u32>) {
784798
// 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));
788801
}
789802

790803
match (!before.is_empty(), !after.is_empty()) {
791804
(_, true) => {
792-
self.hunks.push(Change::AddedOrReplaced(
805+
hunks.push(Change::AddedOrReplaced(
793806
after.start..after.end,
794807
before.end - before.start,
795808
));
796809
}
797810
(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));
799812
}
800813
(false, false) => unreachable!("BUG: imara-diff provided a non-change"),
801814
}
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-
}
813815

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;
828817

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+
});
836820

837-
let res = gix_diff::blob::diff(diff_algorithm, &input, change_recorder);
838821
stats.blobs_diffed += 1;
839-
Ok(res)
822+
Ok(changes.0)
840823
}
841824

842825
fn find_path_entry_in_commit(

gix-blame/tests/blame.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,12 @@ mktest!(
292292
3
293293
);
294294

295-
/// As of 2024-09-24, these tests are expected to fail.
295+
/// As of 2024-09-24, the Myers-related test was expected to fail. Both tests were initially
296+
/// written when diffing was done by `imara-diff` 0.1. After updating to `imara-diff` 0.2 on
297+
/// 2025-12-07, the Myers-related test started passing.
296298
///
297299
/// Context: https://github.com/Byron/gitoxide/pull/1453#issuecomment-2371013904
298300
#[test]
299-
#[should_panic = "empty-lines-myers"]
300301
fn diff_disparity() {
301302
for case in ["empty-lines-myers", "empty-lines-histogram"] {
302303
let Fixture {

0 commit comments

Comments
 (0)