1
1
use gix_object:: TreeRefIter ;
2
2
3
- use super :: { change, Action , Change , Platform } ;
4
- use crate :: {
5
- bstr:: BStr ,
6
- diff:: { rewrites, rewrites:: tracker} ,
7
- ext:: ObjectIdExt ,
8
- object:: tree:: diff,
9
- Repository , Tree ,
10
- } ;
3
+ use super :: { Action , Change , Platform } ;
4
+ use crate :: { diff:: rewrites:: tracker, Tree } ;
11
5
12
6
/// The error return by methods on the [diff platform][Platform].
13
7
#[ derive( Debug , thiserror:: Error ) ]
14
8
#[ allow( missing_docs) ]
15
9
pub enum Error {
16
10
#[ error( transparent) ]
17
- Diff ( #[ from] gix_diff:: tree :: Error ) ,
11
+ Diff ( #[ from] gix_diff:: tree_with_rewrites :: Error ) ,
18
12
#[ error( "The user-provided callback failed" ) ]
19
13
ForEach ( #[ source] Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
20
14
#[ error( transparent) ]
@@ -23,13 +17,6 @@ pub enum Error {
23
17
RenameTracking ( #[ from] tracker:: emit:: Error ) ,
24
18
}
25
19
26
- ///
27
- #[ derive( Clone , Debug , Copy , PartialEq ) ]
28
- pub struct Outcome {
29
- /// Available only if [rewrite-tracking was enabled][Platform::track_rewrites()].
30
- pub rewrites : Option < rewrites:: Outcome > ,
31
- }
32
-
33
20
/// Add the item to compare to.
34
21
impl < ' old > Platform < ' _ , ' old > {
35
22
/// Call `for_each` repeatedly with all changes that are needed to convert the source of the diff to the tree to `other`.
@@ -40,7 +27,7 @@ impl<'old> Platform<'_, 'old> {
40
27
& mut self ,
41
28
other : & Tree < ' new > ,
42
29
for_each : impl FnMut ( Change < ' _ , ' old , ' new > ) -> Result < Action , E > ,
43
- ) -> Result < Outcome , Error >
30
+ ) -> Result < Option < gix_diff :: rewrites :: Outcome > , Error >
44
31
where
45
32
E : Into < Box < dyn std:: error:: Error + Sync + Send + ' static > > ,
46
33
{
@@ -62,7 +49,7 @@ impl<'old> Platform<'_, 'old> {
62
49
other : & Tree < ' new > ,
63
50
resource_cache : & mut gix_diff:: blob:: Platform ,
64
51
for_each : impl FnMut ( Change < ' _ , ' old , ' new > ) -> Result < Action , E > ,
65
- ) -> Result < Outcome , Error >
52
+ ) -> Result < Option < gix_diff :: rewrites :: Outcome > , Error >
66
53
where
67
54
E : Into < Box < dyn std:: error:: Error + Sync + Send + ' static > > ,
68
55
{
@@ -72,289 +59,37 @@ impl<'old> Platform<'_, 'old> {
72
59
fn for_each_to_obtain_tree_inner < ' new , E > (
73
60
& mut self ,
74
61
other : & Tree < ' new > ,
75
- for_each : impl FnMut ( Change < ' _ , ' old , ' new > ) -> Result < Action , E > ,
62
+ mut for_each : impl FnMut ( Change < ' _ , ' old , ' new > ) -> Result < Action , E > ,
76
63
resource_cache : Option < & mut gix_diff:: blob:: Platform > ,
77
- ) -> Result < Outcome , Error >
64
+ ) -> Result < Option < gix_diff :: rewrites :: Outcome > , Error >
78
65
where
79
66
E : Into < Box < dyn std:: error:: Error + Sync + Send + ' static > > ,
80
67
{
81
68
let repo = self . lhs . repo ;
82
- let mut delegate = Delegate {
83
- src_tree : self . lhs ,
84
- other_repo : other. repo ,
85
- recorder : gix_diff:: tree:: Recorder :: default ( ) . track_location ( self . tracking ) ,
86
- visit : for_each,
87
- location : self . tracking ,
88
- tracked : self . rewrites . map ( rewrites:: Tracker :: new) ,
89
- err : None ,
90
- } ;
91
- match gix_diff:: tree (
92
- TreeRefIter :: from_bytes ( & self . lhs . data ) ,
93
- TreeRefIter :: from_bytes ( & other. data ) ,
94
- & mut self . state ,
95
- & repo. objects ,
96
- & mut delegate,
97
- ) {
98
- Ok ( ( ) ) => {
99
- let outcome = Outcome {
100
- rewrites : delegate. process_tracked_changes ( resource_cache) ?,
101
- } ;
102
- match delegate. err {
103
- Some ( err) => Err ( Error :: ForEach ( err. into ( ) ) ) ,
104
- None => Ok ( outcome) ,
105
- }
106
- }
107
- Err ( gix_diff:: tree:: Error :: Cancelled ) => delegate
108
- . err
109
- . map_or ( Err ( Error :: Diff ( gix_diff:: tree:: Error :: Cancelled ) ) , |err| {
110
- Err ( Error :: ForEach ( err. into ( ) ) )
111
- } ) ,
112
- Err ( err) => Err ( err. into ( ) ) ,
113
- }
114
- }
115
- }
116
-
117
- struct Delegate < ' a , ' old , ' new , VisitFn , E > {
118
- src_tree : & ' a Tree < ' old > ,
119
- other_repo : & ' new Repository ,
120
- recorder : gix_diff:: tree:: Recorder ,
121
- visit : VisitFn ,
122
- tracked : Option < rewrites:: Tracker < gix_diff:: tree:: visit:: Change > > ,
123
- location : Option < gix_diff:: tree:: recorder:: Location > ,
124
- err : Option < E > ,
125
- }
126
-
127
- impl < ' old , ' new , VisitFn , E > Delegate < ' _ , ' old , ' new , VisitFn , E >
128
- where
129
- VisitFn : for < ' delegate > FnMut ( Change < ' delegate , ' old , ' new > ) -> Result < Action , E > ,
130
- E : Into < Box < dyn std:: error:: Error + Sync + Send + ' static > > ,
131
- {
132
- /// Call `visit` on an attached version of `change`.
133
- fn emit_change (
134
- change : gix_diff:: tree:: visit:: Change ,
135
- location : & BStr ,
136
- visit : & mut VisitFn ,
137
- repo : & ' old Repository ,
138
- other_repo : & ' new Repository ,
139
- stored_err : & mut Option < E > ,
140
- ) -> gix_diff:: tree:: visit:: Action {
141
- use gix_diff:: tree:: visit:: Change :: * ;
142
- let event = match change {
143
- Addition {
144
- entry_mode,
145
- oid,
146
- relation : _,
147
- } => change:: Event :: Addition {
148
- entry_mode,
149
- id : oid. attach ( other_repo) ,
150
- } ,
151
- Deletion {
152
- entry_mode,
153
- oid,
154
- relation : _,
155
- } => change:: Event :: Deletion {
156
- entry_mode,
157
- id : oid. attach ( repo) ,
158
- } ,
159
- Modification {
160
- previous_entry_mode,
161
- previous_oid,
162
- entry_mode,
163
- oid,
164
- } => change:: Event :: Modification {
165
- previous_entry_mode,
166
- entry_mode,
167
- previous_id : previous_oid. attach ( repo) ,
168
- id : oid. attach ( other_repo) ,
169
- } ,
170
- } ;
171
- match visit ( Change { event, location } ) {
172
- Ok ( Action :: Cancel ) => gix_diff:: tree:: visit:: Action :: Cancel ,
173
- Ok ( Action :: Continue ) => gix_diff:: tree:: visit:: Action :: Continue ,
174
- Err ( err) => {
175
- * stored_err = Some ( err) ;
176
- gix_diff:: tree:: visit:: Action :: Cancel
177
- }
178
- }
179
- }
180
-
181
- fn process_tracked_changes (
182
- & mut self ,
183
- diff_cache : Option < & mut gix_diff:: blob:: Platform > ,
184
- ) -> Result < Option < rewrites:: Outcome > , Error > {
185
- let tracked = match self . tracked . as_mut ( ) {
186
- Some ( t) => t,
187
- None => return Ok ( None ) ,
188
- } ;
189
-
190
- let repo = self . src_tree . repo ;
191
69
let mut storage;
192
- let diff_cache = match diff_cache {
193
- Some ( cache) => cache,
70
+ let cache = match resource_cache {
194
71
None => {
195
72
storage = repo. diff_resource_cache ( gix_diff:: blob:: pipeline:: Mode :: ToGit , Default :: default ( ) ) ?;
196
73
& mut storage
197
74
}
75
+ Some ( cache) => cache,
198
76
} ;
199
-
200
- let outcome = tracked. emit (
201
- |dest, source| match source {
202
- Some ( source) => {
203
- let ( oid, mode) = dest. change . oid_and_entry_mode ( ) ;
204
- let change = diff:: Change {
205
- location : dest. location ,
206
- event : diff:: change:: Event :: Rewrite {
207
- source_location : source. location ,
208
- source_entry_mode : source. entry_mode ,
209
- source_id : source. id . attach ( self . src_tree . repo ) ,
210
- entry_mode : mode,
211
- id : oid. to_owned ( ) . attach ( self . other_repo ) ,
212
- diff : source. diff ,
213
- copy : match source. kind {
214
- tracker:: visit:: SourceKind :: Rename => false ,
215
- tracker:: visit:: SourceKind :: Copy => true ,
216
- } ,
217
- } ,
218
- } ;
219
- match ( self . visit ) ( change) {
220
- Ok ( Action :: Cancel ) => gix_diff:: tree:: visit:: Action :: Cancel ,
221
- Ok ( Action :: Continue ) => gix_diff:: tree:: visit:: Action :: Continue ,
222
- Err ( err) => {
223
- self . err = Some ( err) ;
224
- gix_diff:: tree:: visit:: Action :: Cancel
225
- }
226
- }
227
- }
228
- None => Self :: emit_change (
229
- dest. change ,
230
- dest. location ,
231
- & mut self . visit ,
232
- self . src_tree . repo ,
233
- self . other_repo ,
234
- & mut self . err ,
235
- ) ,
77
+ Ok ( gix_diff:: tree_with_rewrites (
78
+ TreeRefIter :: from_bytes ( & self . lhs . data ) ,
79
+ TreeRefIter :: from_bytes ( & other. data ) ,
80
+ cache,
81
+ & mut self . state ,
82
+ & repo. objects ,
83
+ |change| {
84
+ for_each ( Change :: from_change_ref ( change, repo, other. repo ) ) . map ( |action| match action {
85
+ Action :: Continue => gix_diff:: tree_with_rewrites:: Action :: Continue ,
86
+ Action :: Cancel => gix_diff:: tree_with_rewrites:: Action :: Cancel ,
87
+ } )
236
88
} ,
237
- diff_cache,
238
- & self . src_tree . repo . objects ,
239
- |push| {
240
- self . src_tree
241
- . traverse ( )
242
- . breadthfirst ( & mut tree_to_changes:: Delegate :: new ( push, self . location ) )
89
+ gix_diff:: tree_with_rewrites:: Options {
90
+ location : self . location ,
91
+ rewrites : self . rewrites ,
243
92
} ,
244
- ) ?;
245
- Ok ( Some ( outcome) )
246
- }
247
- }
248
-
249
- impl < ' old , ' new , VisitFn , E > gix_diff:: tree:: Visit for Delegate < ' _ , ' old , ' new , VisitFn , E >
250
- where
251
- VisitFn : for < ' delegate > FnMut ( Change < ' delegate , ' old , ' new > ) -> Result < Action , E > ,
252
- E : Into < Box < dyn std:: error:: Error + Sync + Send + ' static > > ,
253
- {
254
- fn pop_front_tracked_path_and_set_current ( & mut self ) {
255
- self . recorder . pop_front_tracked_path_and_set_current ( ) ;
256
- }
257
-
258
- fn push_back_tracked_path_component ( & mut self , component : & BStr ) {
259
- self . recorder . push_back_tracked_path_component ( component) ;
260
- }
261
-
262
- fn push_path_component ( & mut self , component : & BStr ) {
263
- self . recorder . push_path_component ( component) ;
264
- }
265
-
266
- fn pop_path_component ( & mut self ) {
267
- self . recorder . pop_path_component ( ) ;
268
- }
269
-
270
- fn visit ( & mut self , change : gix_diff:: tree:: visit:: Change ) -> gix_diff:: tree:: visit:: Action {
271
- match self . tracked . as_mut ( ) {
272
- Some ( tracked) => tracked. try_push_change ( change, self . recorder . path ( ) ) . map_or (
273
- gix_diff:: tree:: visit:: Action :: Continue ,
274
- |change| {
275
- Self :: emit_change (
276
- change,
277
- self . recorder . path ( ) ,
278
- & mut self . visit ,
279
- self . src_tree . repo ,
280
- self . other_repo ,
281
- & mut self . err ,
282
- )
283
- } ,
284
- ) ,
285
- None => Self :: emit_change (
286
- change,
287
- self . recorder . path ( ) ,
288
- & mut self . visit ,
289
- self . src_tree . repo ,
290
- self . other_repo ,
291
- & mut self . err ,
292
- ) ,
293
- }
294
- }
295
- }
296
-
297
- mod tree_to_changes {
298
- use gix_diff:: tree:: visit:: Change ;
299
- use gix_object:: tree:: EntryRef ;
300
-
301
- use crate :: bstr:: BStr ;
302
-
303
- pub struct Delegate < ' a > {
304
- push : & ' a mut dyn FnMut ( Change , & BStr ) ,
305
- recorder : gix_traverse:: tree:: Recorder ,
306
- }
307
-
308
- impl < ' a > Delegate < ' a > {
309
- pub fn new (
310
- push : & ' a mut dyn FnMut ( Change , & BStr ) ,
311
- location : Option < gix_diff:: tree:: recorder:: Location > ,
312
- ) -> Self {
313
- let location = location. map ( |t| match t {
314
- gix_diff:: tree:: recorder:: Location :: FileName => gix_traverse:: tree:: recorder:: Location :: FileName ,
315
- gix_diff:: tree:: recorder:: Location :: Path => gix_traverse:: tree:: recorder:: Location :: Path ,
316
- } ) ;
317
- Self {
318
- push,
319
- recorder : gix_traverse:: tree:: Recorder :: default ( ) . track_location ( location) ,
320
- }
321
- }
322
- }
323
-
324
- impl gix_traverse:: tree:: Visit for Delegate < ' _ > {
325
- fn pop_front_tracked_path_and_set_current ( & mut self ) {
326
- self . recorder . pop_front_tracked_path_and_set_current ( ) ;
327
- }
328
-
329
- fn push_back_tracked_path_component ( & mut self , component : & BStr ) {
330
- self . recorder . push_back_tracked_path_component ( component) ;
331
- }
332
-
333
- fn push_path_component ( & mut self , component : & BStr ) {
334
- self . recorder . push_path_component ( component) ;
335
- }
336
-
337
- fn pop_path_component ( & mut self ) {
338
- self . recorder . pop_path_component ( ) ;
339
- }
340
-
341
- fn visit_tree ( & mut self , _entry : & EntryRef < ' _ > ) -> gix_traverse:: tree:: visit:: Action {
342
- gix_traverse:: tree:: visit:: Action :: Continue
343
- }
344
-
345
- fn visit_nontree ( & mut self , entry : & EntryRef < ' _ > ) -> gix_traverse:: tree:: visit:: Action {
346
- if entry. mode . is_blob ( ) {
347
- ( self . push ) (
348
- Change :: Modification {
349
- previous_entry_mode : entry. mode ,
350
- previous_oid : gix_hash:: ObjectId :: null ( entry. oid . kind ( ) ) ,
351
- entry_mode : entry. mode ,
352
- oid : entry. oid . to_owned ( ) ,
353
- } ,
354
- self . recorder . path ( ) ,
355
- ) ;
356
- }
357
- gix_traverse:: tree:: visit:: Action :: Continue
358
- }
93
+ ) ?)
359
94
}
360
95
}
0 commit comments