1
- use gix_object:: TreeRefIter ;
1
+ use gix_object:: { FindExt , TreeRefIter } ;
2
2
3
3
use 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 } ;
13
6
14
7
/// The error return by methods on the [diff platform][Platform].
15
8
#[ derive( Debug , thiserror:: Error ) ]
@@ -19,12 +12,10 @@ pub enum Error {
19
12
Diff ( #[ from] gix_diff:: tree:: changes:: Error ) ,
20
13
#[ error( "The user-provided callback failed" ) ]
21
14
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 ) ,
24
15
#[ error( "Could not configure diff algorithm prior to checking similarity" ) ]
25
16
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 ) ,
28
19
}
29
20
30
21
///
@@ -49,12 +40,14 @@ impl<'a, 'old> Platform<'a, 'old> {
49
40
E : std:: error:: Error + Sync + Send + ' static ,
50
41
{
51
42
let repo = self . lhs . repo ;
43
+ let diff_algo = repo. config . diff_algorithm ( ) ?;
52
44
let mut delegate = Delegate {
53
45
src_tree : self . lhs ,
54
46
other_repo : other. repo ,
55
47
recorder : gix_diff:: tree:: Recorder :: default ( ) . track_location ( self . tracking ) ,
56
48
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) ) ,
58
51
err : None ,
59
52
} ;
60
53
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> {
87
80
other_repo : & ' new Repository ,
88
81
recorder : gix_diff:: tree:: Recorder ,
89
82
visit : VisitFn ,
90
- tracked : Option < tracked:: State > ,
83
+ tracked : Option < rewrites:: Tracker > ,
84
+ location : Option < gix_diff:: tree:: recorder:: Location > ,
91
85
err : Option < E > ,
92
86
}
93
87
@@ -157,8 +151,8 @@ where
157
151
id : oid. to_owned ( ) . attach ( self . other_repo ) ,
158
152
diff : source. diff ,
159
153
copy : match source. kind {
160
- tracked :: visit:: Kind :: RenameTarget => false ,
161
- tracked :: visit:: Kind :: CopyDestination => true ,
154
+ tracker :: visit:: Kind :: RenameTarget => false ,
155
+ tracker :: visit:: Kind :: CopyDestination => true ,
162
156
} ,
163
157
} ,
164
158
} ;
@@ -180,7 +174,12 @@ where
180
174
& mut self . err ,
181
175
) ,
182
176
} ,
183
- self . src_tree ,
177
+ |oid, buf| self . src_tree . repo . objects . find_blob ( oid, buf) ,
178
+ |push| {
179
+ self . src_tree
180
+ . traverse ( )
181
+ . breadthfirst ( & mut tree_to_changes:: Delegate :: new ( push, self . location ) )
182
+ } ,
184
183
) ?;
185
184
Ok ( Some ( outcome) )
186
185
}
@@ -233,3 +232,68 @@ where
233
232
}
234
233
}
235
234
}
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