Skip to content

Commit df81577

Browse files
committed
feat!: Provide more source information when emitting rewrites.
Previously, the source was entirely missing, now it's also made available. Further, all the cloning of these resources is now left to the user, which should safe time.
1 parent 697ac28 commit df81577

File tree

6 files changed

+44
-14
lines changed

6 files changed

+44
-14
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gix-diff/src/rewrites/tracker.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ pub mod visit {
8383

8484
/// The source of a rewrite, rename or copy.
8585
#[derive(Debug, Clone, PartialEq, PartialOrd)]
86-
pub struct Source<'a> {
86+
pub struct Source<'a, T> {
8787
/// The kind of entry.
8888
pub entry_mode: EntryMode,
8989
/// The hash of the state of the source as seen in the object database.
@@ -92,6 +92,8 @@ pub mod visit {
9292
pub kind: SourceKind,
9393
/// The repository-relative location of this entry.
9494
pub location: &'a BStr,
95+
/// The change that was registered as source.
96+
pub change: &'a T,
9597
/// If this is a rewrite, indicate how many lines would need to change to turn this source into the destination.
9698
pub diff: Option<DiffLineStats>,
9799
}
@@ -193,7 +195,7 @@ impl<T: Change> Tracker<T> {
193195
/// will panic if `change` is not a modification, and it's valid to not call `push` at all.
194196
pub fn emit<PushSourceTreeFn, E>(
195197
&mut self,
196-
mut cb: impl FnMut(visit::Destination<'_, T>, Option<visit::Source<'_>>) -> crate::tree::visit::Action,
198+
mut cb: impl FnMut(visit::Destination<'_, T>, Option<visit::Source<'_, T>>) -> crate::tree::visit::Action,
197199
diff_cache: &mut crate::blob::Platform,
198200
objects: &impl gix_object::FindObjectOrHeader,
199201
mut push_source_tree: PushSourceTreeFn,
@@ -283,7 +285,7 @@ impl<T: Change> Tracker<T> {
283285
fn match_pairs_of_kind(
284286
&mut self,
285287
kind: visit::SourceKind,
286-
cb: &mut impl FnMut(visit::Destination<'_, T>, Option<visit::Source<'_>>) -> crate::tree::visit::Action,
288+
cb: &mut impl FnMut(visit::Destination<'_, T>, Option<visit::Source<'_, T>>) -> crate::tree::visit::Action,
287289
percentage: Option<f32>,
288290
out: &mut Outcome,
289291
diff_cache: &mut crate::blob::Platform,
@@ -326,7 +328,7 @@ impl<T: Change> Tracker<T> {
326328

327329
fn match_pairs(
328330
&mut self,
329-
cb: &mut impl FnMut(visit::Destination<'_, T>, Option<visit::Source<'_>>) -> crate::tree::visit::Action,
331+
cb: &mut impl FnMut(visit::Destination<'_, T>, Option<visit::Source<'_, T>>) -> crate::tree::visit::Action,
330332
percentage: Option<f32>,
331333
kind: visit::SourceKind,
332334
stats: &mut Outcome,
@@ -360,6 +362,7 @@ impl<T: Change> Tracker<T> {
360362
id,
361363
kind,
362364
location,
365+
change: &src.change,
363366
diff,
364367
},
365368
src_idx,
@@ -371,11 +374,15 @@ impl<T: Change> Tracker<T> {
371374
let location = dest.location(&self.path_backing);
372375
let change = dest.change.clone();
373376
let dest = visit::Destination { change, location };
377+
let src_idx = src.as_ref().map(|t| t.1);
378+
let res = cb(dest, src.map(|t| t.0));
379+
374380
self.items[dest_idx].emitted = true;
375-
if let Some(src_idx) = src.as_ref().map(|t| t.1) {
381+
if let Some(src_idx) = src_idx {
376382
self.items[src_idx].emitted = true;
377383
}
378-
if cb(dest, src.map(|t| t.0)) == crate::tree::visit::Action::Cancel {
384+
385+
if res == crate::tree::visit::Action::Cancel {
379386
return Ok(crate::tree::visit::Action::Cancel);
380387
}
381388
}

gix-diff/tests/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ gix-filter = { path = "../../gix-filter" }
2525
gix-traverse = { path = "../../gix-traverse" }
2626
gix-testtools = { path = "../../tests/tools" }
2727
shell-words = "1"
28+
pretty_assertions = "1.4.0"
Binary file not shown.

gix-diff/tests/rewrites/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use gix_object::tree::{EntryKind, EntryMode};
44

55
mod tracker;
66

7-
#[derive(Clone)]
7+
#[derive(Debug, Clone, PartialEq, Eq)]
88
pub struct Change {
99
id: ObjectId,
1010
kind: ChangeKind,

gix-diff/tests/rewrites/tracker.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use gix_diff::{
1212
Rewrites,
1313
};
1414
use gix_object::tree::EntryKind;
15+
use pretty_assertions::assert_eq;
1516

1617
use crate::{
1718
hex_to_id,
@@ -51,6 +52,7 @@ fn rename_by_id() -> crate::Result {
5152
id: NULL_ID,
5253
kind: SourceKind::Rename,
5354
location: "b".into(),
55+
change: &Change::deletion(),
5456
diff: None,
5557
}
5658
);
@@ -146,11 +148,16 @@ fn copy_by_id() -> crate::Result {
146148
let out = util::assert_emit_with_objects(
147149
&mut track,
148150
|dst, src| {
151+
let id = hex_to_id("2e65efe2a145dda7ee51d1741299f848e5bf752e");
149152
let source_a = Source {
150153
entry_mode: EntryKind::Blob.into(),
151-
id: hex_to_id("2e65efe2a145dda7ee51d1741299f848e5bf752e"),
154+
id: id,
152155
kind: SourceKind::Copy,
153156
location: "a".into(),
157+
change: &Change {
158+
id,
159+
..Change::modification()
160+
},
154161
diff: None,
155162
};
156163
match calls {
@@ -219,6 +226,10 @@ fn copy_by_id_search_in_all_sources() -> crate::Result {
219226
id: content_id,
220227
kind: SourceKind::Copy,
221228
location: "a-src".into(),
229+
change: &Change {
230+
id: content_id,
231+
..Change::modification()
232+
},
222233
diff: None,
223234
};
224235
match calls {
@@ -289,11 +300,16 @@ fn copy_by_50_percent_similarity() -> crate::Result {
289300
let out = util::assert_emit_with_objects(
290301
&mut track,
291302
|dst, src| {
303+
let id = hex_to_id("78981922613b2afb6025042ff6bd878ac1994e85");
292304
let source_a = Source {
293305
entry_mode: EntryKind::Blob.into(),
294-
id: hex_to_id("78981922613b2afb6025042ff6bd878ac1994e85"),
306+
id: id,
295307
kind: SourceKind::Copy,
296308
location: "a".into(),
309+
change: &Change {
310+
id,
311+
..Change::modification()
312+
},
297313
diff: Some(DiffLineStats {
298314
removals: 0,
299315
insertions: 1,
@@ -459,13 +475,18 @@ fn rename_by_50_percent_similarity() -> crate::Result {
459475
|dst, src| {
460476
match calls {
461477
0 => {
478+
let id = hex_to_id("66a52ee7a1d803dc57859c3e95ac9dcdc87c0164");
462479
assert_eq!(
463480
src.unwrap(),
464481
Source {
465482
entry_mode: EntryKind::Blob.into(),
466-
id: hex_to_id("66a52ee7a1d803dc57859c3e95ac9dcdc87c0164"),
483+
id: id,
467484
kind: SourceKind::Rename,
468485
location: "a".into(),
486+
change: &Change {
487+
id,
488+
..Change::deletion()
489+
},
469490
diff: Some(DiffLineStats {
470491
removals: 1,
471492
insertions: 1,
@@ -532,7 +553,7 @@ fn add_only() -> crate::Result {
532553
let out = util::assert_emit(&mut track, |dst, src| {
533554
assert!(!called);
534555
called = true;
535-
assert_eq!(src, None, "there is just a single deletion, no pair");
556+
assert!(src.is_none(), "there is just a single deletion, no pair");
536557
assert_eq!(dst.location, "a");
537558
assert_eq!(dst.change.kind, ChangeKind::Addition);
538559
Action::Continue
@@ -569,22 +590,22 @@ mod util {
569590

570591
pub fn assert_emit(
571592
tracker: &mut rewrites::Tracker<Change>,
572-
cb: impl FnMut(Destination<'_, Change>, Option<Source<'_>>) -> Action,
593+
cb: impl FnMut(Destination<'_, Change>, Option<Source<'_, Change>>) -> Action,
573594
) -> rewrites::Outcome {
574595
assert_emit_with_objects(tracker, cb, gix_object::find::Never)
575596
}
576597

577598
pub fn assert_emit_with_objects(
578599
tracker: &mut rewrites::Tracker<Change>,
579-
cb: impl FnMut(Destination<'_, Change>, Option<Source<'_>>) -> Action,
600+
cb: impl FnMut(Destination<'_, Change>, Option<Source<'_, Change>>) -> Action,
580601
objects: impl gix_object::FindObjectOrHeader,
581602
) -> rewrites::Outcome {
582603
assert_emit_with_objects_and_sources(tracker, cb, objects, None)
583604
}
584605

585606
pub fn assert_emit_with_objects_and_sources<'a>(
586607
tracker: &mut rewrites::Tracker<Change>,
587-
cb: impl FnMut(Destination<'_, Change>, Option<Source<'_>>) -> Action,
608+
cb: impl FnMut(Destination<'_, Change>, Option<Source<'_, Change>>) -> Action,
588609
objects: impl gix_object::FindObjectOrHeader,
589610
sources: impl IntoIterator<Item = (Change, &'a str)>,
590611
) -> rewrites::Outcome {

0 commit comments

Comments
 (0)