@@ -2,15 +2,8 @@ use gix_object::TreeRefIter;
2
2
use gix_odb:: FindExt ;
3
3
4
4
use super :: { change, Action , Change , Platform } ;
5
- use crate :: {
6
- bstr:: BStr ,
7
- ext:: ObjectIdExt ,
8
- object:: tree:: {
9
- diff,
10
- diff:: { rewrites, tracked} ,
11
- } ,
12
- Repository , Tree ,
13
- } ;
5
+ use crate :: diff:: rewrites:: tracker;
6
+ use crate :: { bstr:: BStr , diff:: rewrites, ext:: ObjectIdExt , object:: tree:: diff, Repository , Tree } ;
14
7
15
8
/// The error return by methods on the [diff platform][Platform].
16
9
#[ derive( Debug , thiserror:: Error ) ]
@@ -20,12 +13,10 @@ pub enum Error {
20
13
Diff ( #[ from] gix_diff:: tree:: changes:: Error ) ,
21
14
#[ error( "The user-provided callback failed" ) ]
22
15
ForEach ( #[ source] Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
23
- #[ error( "Could not find blob for similarity checking" ) ]
24
- FindExistingBlob ( #[ from] crate :: object:: find:: existing:: Error ) ,
25
16
#[ error( "Could not configure diff algorithm prior to checking similarity" ) ]
26
17
ConfigureDiffAlgorithm ( #[ from] crate :: config:: diff:: algorithm:: Error ) ,
27
- #[ error( "Could not traverse tree to obtain possible sources for copies " ) ]
28
- TraverseTreeForExhaustiveCopyDetection ( #[ from] gix_traverse :: tree :: breadthfirst :: Error ) ,
18
+ #[ error( "Failure during rename tracking " ) ]
19
+ RenameTracking ( #[ from] tracker :: emit :: Error ) ,
29
20
}
30
21
31
22
///
@@ -50,12 +41,14 @@ impl<'a, 'old> Platform<'a, 'old> {
50
41
E : std:: error:: Error + Sync + Send + ' static ,
51
42
{
52
43
let repo = self . lhs . repo ;
44
+ let diff_algo = repo. config . diff_algorithm ( ) ?;
53
45
let mut delegate = Delegate {
54
46
src_tree : self . lhs ,
55
47
other_repo : other. repo ,
56
48
recorder : gix_diff:: tree:: Recorder :: default ( ) . track_location ( self . tracking ) ,
57
49
visit : for_each,
58
- tracked : self . rewrites . map ( |r| tracked:: State :: new ( r, self . tracking ) ) ,
50
+ location : self . tracking ,
51
+ tracked : self . rewrites . map ( |r| rewrites:: Tracker :: new ( r, diff_algo) ) ,
59
52
err : None ,
60
53
} ;
61
54
match gix_diff:: tree:: Changes :: from ( TreeRefIter :: from_bytes ( & self . lhs . data ) ) . needed_to_obtain (
@@ -88,7 +81,8 @@ struct Delegate<'a, 'old, 'new, VisitFn, E> {
88
81
other_repo : & ' new Repository ,
89
82
recorder : gix_diff:: tree:: Recorder ,
90
83
visit : VisitFn ,
91
- tracked : Option < tracked:: State > ,
84
+ tracked : Option < rewrites:: Tracker > ,
85
+ location : Option < gix_diff:: tree:: recorder:: Location > ,
92
86
err : Option < E > ,
93
87
}
94
88
@@ -158,8 +152,8 @@ where
158
152
id : oid. to_owned ( ) . attach ( self . other_repo ) ,
159
153
diff : source. diff ,
160
154
copy : match source. kind {
161
- tracked :: visit:: Kind :: RenameTarget => false ,
162
- tracked :: visit:: Kind :: CopyDestination => true ,
155
+ tracker :: visit:: Kind :: RenameTarget => false ,
156
+ tracker :: visit:: Kind :: CopyDestination => true ,
163
157
} ,
164
158
} ,
165
159
} ;
@@ -181,7 +175,12 @@ where
181
175
& mut self . err ,
182
176
) ,
183
177
} ,
184
- self . src_tree ,
178
+ |oid, buf| self . src_tree . repo . objects . find_blob ( oid, buf) ,
179
+ |push| {
180
+ self . src_tree
181
+ . traverse ( )
182
+ . breadthfirst ( & mut tree_to_changes:: Delegate :: new ( push, self . location ) )
183
+ } ,
185
184
) ?;
186
185
Ok ( Some ( outcome) )
187
186
}
@@ -234,3 +233,68 @@ where
234
233
}
235
234
}
236
235
}
236
+
237
+ mod tree_to_changes {
238
+ use gix_diff:: tree:: visit:: Change ;
239
+ use gix_object:: tree:: EntryRef ;
240
+
241
+ use crate :: bstr:: BStr ;
242
+
243
+ pub struct Delegate < ' a > {
244
+ push : & ' a mut dyn FnMut ( Change , & BStr ) ,
245
+ recorder : gix_traverse:: tree:: Recorder ,
246
+ }
247
+
248
+ impl < ' a > Delegate < ' a > {
249
+ pub fn new (
250
+ push : & ' a mut dyn FnMut ( Change , & BStr ) ,
251
+ location : Option < gix_diff:: tree:: recorder:: Location > ,
252
+ ) -> Self {
253
+ let location = location. map ( |t| match t {
254
+ gix_diff:: tree:: recorder:: Location :: FileName => gix_traverse:: tree:: recorder:: Location :: FileName ,
255
+ gix_diff:: tree:: recorder:: Location :: Path => gix_traverse:: tree:: recorder:: Location :: Path ,
256
+ } ) ;
257
+ Self {
258
+ push,
259
+ recorder : gix_traverse:: tree:: Recorder :: default ( ) . track_location ( location) ,
260
+ }
261
+ }
262
+ }
263
+
264
+ impl gix_traverse:: tree:: Visit for Delegate < ' _ > {
265
+ fn pop_front_tracked_path_and_set_current ( & mut self ) {
266
+ self . recorder . pop_front_tracked_path_and_set_current ( )
267
+ }
268
+
269
+ fn push_back_tracked_path_component ( & mut self , component : & BStr ) {
270
+ self . recorder . push_back_tracked_path_component ( component)
271
+ }
272
+
273
+ fn push_path_component ( & mut self , component : & BStr ) {
274
+ self . recorder . push_path_component ( component)
275
+ }
276
+
277
+ fn pop_path_component ( & mut self ) {
278
+ self . recorder . pop_path_component ( ) ;
279
+ }
280
+
281
+ fn visit_tree ( & mut self , _entry : & EntryRef < ' _ > ) -> gix_traverse:: tree:: visit:: Action {
282
+ gix_traverse:: tree:: visit:: Action :: Continue
283
+ }
284
+
285
+ fn visit_nontree ( & mut self , entry : & EntryRef < ' _ > ) -> gix_traverse:: tree:: visit:: Action {
286
+ if entry. mode . is_blob ( ) {
287
+ ( self . push ) (
288
+ Change :: Modification {
289
+ previous_entry_mode : entry. mode ,
290
+ previous_oid : gix_hash:: ObjectId :: null ( entry. oid . kind ( ) ) ,
291
+ entry_mode : entry. mode ,
292
+ oid : entry. oid . to_owned ( ) ,
293
+ } ,
294
+ self . recorder . path ( ) ,
295
+ ) ;
296
+ }
297
+ gix_traverse:: tree:: visit:: Action :: Continue
298
+ }
299
+ }
300
+ }
0 commit comments