11use gix_object:: TreeRefIter ;
22
33use super :: { change, Action , Change , Platform } ;
4- use crate :: {
5- bstr:: BStr ,
6- ext:: ObjectIdExt ,
7- object:: tree:: {
8- diff,
9- diff:: { rewrites, tracked} ,
10- } ,
11- Repository , Tree ,
12- } ;
4+ use crate :: diff:: rewrites:: tracker;
5+ use crate :: { bstr:: BStr , diff:: rewrites, ext:: ObjectIdExt , object:: tree:: diff, Repository , Tree } ;
136
147/// The error return by methods on the [diff platform][Platform].
158#[ derive( Debug , thiserror:: Error ) ]
@@ -19,12 +12,10 @@ pub enum Error {
1912 Diff ( #[ from] gix_diff:: tree:: changes:: Error ) ,
2013 #[ error( "The user-provided callback failed" ) ]
2114 ForEach ( #[ source] Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
22- #[ error( "Could not find blob for similarity checking" ) ]
23- FindExistingBlob ( #[ from] crate :: object:: find:: existing:: Error ) ,
2415 #[ error( "Could not configure diff algorithm prior to checking similarity" ) ]
2516 ConfigureDiffAlgorithm ( #[ from] crate :: config:: diff:: algorithm:: Error ) ,
26- #[ error( "Could not traverse tree to obtain possible sources for copies " ) ]
27- TraverseTreeForExhaustiveCopyDetection ( #[ from] gix_traverse :: tree :: breadthfirst :: Error ) ,
17+ #[ error( "Failure during rename tracking " ) ]
18+ RenameTracking ( #[ from] tracker :: emit :: Error ) ,
2819}
2920
3021///
@@ -49,12 +40,14 @@ impl<'a, 'old> Platform<'a, 'old> {
4940 E : std:: error:: Error + Sync + Send + ' static ,
5041 {
5142 let repo = self . lhs . repo ;
43+ let diff_algo = repo. config . diff_algorithm ( ) ?;
5244 let mut delegate = Delegate {
5345 src_tree : self . lhs ,
5446 other_repo : other. repo ,
5547 recorder : gix_diff:: tree:: Recorder :: default ( ) . track_location ( self . tracking ) ,
5648 visit : for_each,
57- tracked : self . rewrites . map ( |r| tracked:: State :: new ( r, self . tracking ) ) ,
49+ location : self . tracking ,
50+ tracked : self . rewrites . map ( |r| rewrites:: Tracker :: new ( r, diff_algo) ) ,
5851 err : None ,
5952 } ;
6053 match gix_diff:: tree:: Changes :: from ( TreeRefIter :: from_bytes ( & self . lhs . data ) ) . needed_to_obtain (
@@ -87,7 +80,8 @@ struct Delegate<'a, 'old, 'new, VisitFn, E> {
8780 other_repo : & ' new Repository ,
8881 recorder : gix_diff:: tree:: Recorder ,
8982 visit : VisitFn ,
90- tracked : Option < tracked:: State > ,
83+ tracked : Option < rewrites:: Tracker < gix_diff:: tree:: visit:: Change > > ,
84+ location : Option < gix_diff:: tree:: recorder:: Location > ,
9185 err : Option < E > ,
9286}
9387
@@ -151,14 +145,14 @@ where
151145 location : dest. location ,
152146 event : diff:: change:: Event :: Rewrite {
153147 source_location : source. location ,
154- source_entry_mode : source. mode ,
148+ source_entry_mode : source. entry_mode ,
155149 source_id : source. id . attach ( self . src_tree . repo ) ,
156150 entry_mode : mode,
157151 id : oid. to_owned ( ) . attach ( self . other_repo ) ,
158152 diff : source. diff ,
159153 copy : match source. kind {
160- tracked :: visit:: Kind :: RenameTarget => false ,
161- tracked :: visit:: Kind :: CopyDestination => true ,
154+ tracker :: visit:: SourceKind :: Rename => false ,
155+ tracker :: visit:: SourceKind :: Copy => true ,
162156 } ,
163157 } ,
164158 } ;
@@ -180,7 +174,12 @@ where
180174 & mut self . err ,
181175 ) ,
182176 } ,
183- self . src_tree ,
177+ & self . src_tree . repo . objects ,
178+ |push| {
179+ self . src_tree
180+ . traverse ( )
181+ . breadthfirst ( & mut tree_to_changes:: Delegate :: new ( push, self . location ) )
182+ } ,
184183 ) ?;
185184 Ok ( Some ( outcome) )
186185 }
@@ -233,3 +232,68 @@ where
233232 }
234233 }
235234}
235+
236+ mod tree_to_changes {
237+ use gix_diff:: tree:: visit:: Change ;
238+ use gix_object:: tree:: EntryRef ;
239+
240+ use crate :: bstr:: BStr ;
241+
242+ pub struct Delegate < ' a > {
243+ push : & ' a mut dyn FnMut ( Change , & BStr ) ,
244+ recorder : gix_traverse:: tree:: Recorder ,
245+ }
246+
247+ impl < ' a > Delegate < ' a > {
248+ pub fn new (
249+ push : & ' a mut dyn FnMut ( Change , & BStr ) ,
250+ location : Option < gix_diff:: tree:: recorder:: Location > ,
251+ ) -> Self {
252+ let location = location. map ( |t| match t {
253+ gix_diff:: tree:: recorder:: Location :: FileName => gix_traverse:: tree:: recorder:: Location :: FileName ,
254+ gix_diff:: tree:: recorder:: Location :: Path => gix_traverse:: tree:: recorder:: Location :: Path ,
255+ } ) ;
256+ Self {
257+ push,
258+ recorder : gix_traverse:: tree:: Recorder :: default ( ) . track_location ( location) ,
259+ }
260+ }
261+ }
262+
263+ impl gix_traverse:: tree:: Visit for Delegate < ' _ > {
264+ fn pop_front_tracked_path_and_set_current ( & mut self ) {
265+ self . recorder . pop_front_tracked_path_and_set_current ( )
266+ }
267+
268+ fn push_back_tracked_path_component ( & mut self , component : & BStr ) {
269+ self . recorder . push_back_tracked_path_component ( component)
270+ }
271+
272+ fn push_path_component ( & mut self , component : & BStr ) {
273+ self . recorder . push_path_component ( component)
274+ }
275+
276+ fn pop_path_component ( & mut self ) {
277+ self . recorder . pop_path_component ( ) ;
278+ }
279+
280+ fn visit_tree ( & mut self , _entry : & EntryRef < ' _ > ) -> gix_traverse:: tree:: visit:: Action {
281+ gix_traverse:: tree:: visit:: Action :: Continue
282+ }
283+
284+ fn visit_nontree ( & mut self , entry : & EntryRef < ' _ > ) -> gix_traverse:: tree:: visit:: Action {
285+ if entry. mode . is_blob ( ) {
286+ ( self . push ) (
287+ Change :: Modification {
288+ previous_entry_mode : entry. mode ,
289+ previous_oid : gix_hash:: ObjectId :: null ( entry. oid . kind ( ) ) ,
290+ entry_mode : entry. mode ,
291+ oid : entry. oid . to_owned ( ) ,
292+ } ,
293+ self . recorder . path ( ) ,
294+ ) ;
295+ }
296+ gix_traverse:: tree:: visit:: Action :: Continue
297+ }
298+ }
299+ }
0 commit comments