1
- use crate :: { bstr:: BStr , diff:: blob:: DiffLineStats , Id } ;
1
+ use crate :: bstr:: BString ;
2
+ use crate :: ext:: ObjectIdExt ;
3
+ use crate :: object:: tree:: diff:: ChangeDetached ;
4
+ use crate :: { bstr:: BStr , diff:: blob:: DiffLineStats , Id , Repository } ;
2
5
3
6
/// An event emitted when finding differences between two trees.
4
7
#[ derive( Debug , Clone , Copy ) ]
@@ -67,6 +70,99 @@ pub enum Event<'a, 'old, 'new> {
67
70
} ,
68
71
}
69
72
73
+ /// An event emitted when finding differences between two trees.
74
+ #[ derive( Debug , Clone ) ]
75
+ pub enum EventDetached {
76
+ /// An entry was added, like the addition of a file or directory.
77
+ Addition {
78
+ /// The mode of the added entry.
79
+ entry_mode : gix_object:: tree:: EntryMode ,
80
+ /// The object id of the added entry.
81
+ id : gix_hash:: ObjectId ,
82
+ } ,
83
+ /// An entry was deleted, like the deletion of a file or directory.
84
+ Deletion {
85
+ /// The mode of the deleted entry.
86
+ entry_mode : gix_object:: tree:: EntryMode ,
87
+ /// The object id of the deleted entry.
88
+ id : gix_hash:: ObjectId ,
89
+ } ,
90
+ /// An entry was modified, e.g. changing the contents of a file adjusts its object id and turning
91
+ /// a file into a symbolic link adjusts its mode.
92
+ Modification {
93
+ /// The mode of the entry before the modification.
94
+ previous_entry_mode : gix_object:: tree:: EntryMode ,
95
+ /// The object id of the entry before the modification.
96
+ previous_id : gix_hash:: ObjectId ,
97
+
98
+ /// The mode of the entry after the modification.
99
+ entry_mode : gix_object:: tree:: EntryMode ,
100
+ /// The object id after the modification.
101
+ id : gix_hash:: ObjectId ,
102
+ } ,
103
+ /// Entries are considered rewritten if they are not trees and they, according to some understanding of identity, were renamed
104
+ /// or copied.
105
+ /// In case of renames, this means they originally appeared as [`Deletion`][Event::Deletion] signalling their source as well as an
106
+ /// [`Addition`][Event::Addition] acting as destination.
107
+ ///
108
+ /// In case of copies, the `copy` flag is true and typically represents a perfect copy of a source was made.
109
+ ///
110
+ /// This variant can only be encountered if [rewrite tracking][super::Platform::track_rewrites()] is enabled.
111
+ ///
112
+ /// Note that mode changes may have occurred as well, i.e. changes from executable to non-executable or vice-versa.
113
+ Rewrite {
114
+ /// The location of the source of the rename operation.
115
+ ///
116
+ /// It may be empty if neither [file names][super::Platform::track_filename()] nor [file paths][super::Platform::track_path()]
117
+ /// are tracked.
118
+ source_location : BString ,
119
+ /// The mode of the entry before the rename.
120
+ source_entry_mode : gix_object:: tree:: EntryMode ,
121
+ /// The object id of the entry before the rename.
122
+ ///
123
+ /// Note that this is the same as `id` if we require the [similarity to be 100%][super::Rewrites::percentage], but may
124
+ /// be different otherwise.
125
+ source_id : gix_hash:: ObjectId ,
126
+ /// Information about the diff we performed to detect similarity and match the `source_id` with the current state at `id`.
127
+ /// It's `None` if `source_id` is equal to `id`, as identity made an actual diff computation unnecessary.
128
+ diff : Option < DiffLineStats > ,
129
+ /// The mode of the entry after the rename.
130
+ /// It could differ but still be considered a rename as we are concerned only about content.
131
+ entry_mode : gix_object:: tree:: EntryMode ,
132
+ /// The object id after the rename.
133
+ id : gix_hash:: ObjectId ,
134
+ /// If true, this rewrite is created by copy, and `source_id` is pointing to its source. Otherwise, it's a rename, and `source_id`
135
+ /// points to a deleted object, as renames are tracked as deletions and additions of the same or similar content.
136
+ copy : bool ,
137
+ } ,
138
+ }
139
+
140
+ /// Lifecycle
141
+ impl super :: Change < ' _ , ' _ , ' _ > {
142
+ /// Detach the repository instance to obtain a fully-owned version
143
+ pub fn detach ( self ) -> ChangeDetached {
144
+ ChangeDetached {
145
+ location : self . location . to_owned ( ) ,
146
+ event : self . event . detach ( ) ,
147
+ }
148
+ }
149
+ }
150
+
151
+ /// Lifecycle
152
+ impl ChangeDetached {
153
+ /// Return an attached version of this instance that uses `old_repo` for previous values and `new_repo` for current values.
154
+ pub fn attach < ' old , ' new > (
155
+ & self ,
156
+ old_repo : & ' old Repository ,
157
+ new_repo : & ' new Repository ,
158
+ ) -> super :: Change < ' _ , ' old , ' new > {
159
+ super :: Change {
160
+ location : self . location . as_ref ( ) ,
161
+ event : self . event . attach ( old_repo, new_repo) ,
162
+ }
163
+ }
164
+ }
165
+
70
166
impl < ' a , ' old , ' new > super :: Change < ' a , ' old , ' new > {
71
167
/// Produce a platform for performing a line-diff no matter whether the underlying [Event] is an addition, modification,
72
168
/// deletion or rewrite.
@@ -86,6 +182,95 @@ impl<'a, 'old, 'new> super::Change<'a, 'old, 'new> {
86
182
}
87
183
}
88
184
185
+ /// Lifecycle
186
+ impl Event < ' _ , ' _ , ' _ > {
187
+ /// Detach the repository instance to obtain a fully-owned version
188
+ pub fn detach ( self ) -> EventDetached {
189
+ match self {
190
+ Event :: Addition { entry_mode, id } => EventDetached :: Addition {
191
+ entry_mode,
192
+ id : id. detach ( ) ,
193
+ } ,
194
+ Event :: Deletion { entry_mode, id } => EventDetached :: Deletion {
195
+ entry_mode,
196
+ id : id. detach ( ) ,
197
+ } ,
198
+ Event :: Modification {
199
+ previous_entry_mode,
200
+ previous_id,
201
+ entry_mode,
202
+ id,
203
+ } => EventDetached :: Modification {
204
+ previous_entry_mode,
205
+ previous_id : previous_id. detach ( ) ,
206
+ entry_mode,
207
+ id : id. detach ( ) ,
208
+ } ,
209
+ Event :: Rewrite {
210
+ source_location,
211
+ source_entry_mode,
212
+ source_id,
213
+ diff,
214
+ entry_mode,
215
+ id,
216
+ copy,
217
+ } => EventDetached :: Rewrite {
218
+ source_location : source_location. to_owned ( ) ,
219
+ source_entry_mode,
220
+ source_id : source_id. detach ( ) ,
221
+ diff,
222
+ entry_mode,
223
+ id : id. detach ( ) ,
224
+ copy,
225
+ } ,
226
+ }
227
+ }
228
+ }
229
+
230
+ impl EventDetached {
231
+ /// Return an attached version of this instance that uses `old_repo` for previous values and `new_repo` for current values.
232
+ pub fn attach < ' old , ' new > ( & self , old_repo : & ' old Repository , new_repo : & ' new Repository ) -> Event < ' _ , ' old , ' new > {
233
+ match self {
234
+ EventDetached :: Addition { entry_mode, id } => Event :: Addition {
235
+ entry_mode : * entry_mode,
236
+ id : id. attach ( new_repo) ,
237
+ } ,
238
+ EventDetached :: Deletion { entry_mode, id } => Event :: Deletion {
239
+ entry_mode : * entry_mode,
240
+ id : id. attach ( old_repo) ,
241
+ } ,
242
+ EventDetached :: Modification {
243
+ previous_entry_mode,
244
+ previous_id,
245
+ entry_mode,
246
+ id,
247
+ } => Event :: Modification {
248
+ previous_entry_mode : * previous_entry_mode,
249
+ previous_id : previous_id. attach ( old_repo) ,
250
+ entry_mode : * entry_mode,
251
+ id : id. attach ( new_repo) ,
252
+ } ,
253
+ EventDetached :: Rewrite {
254
+ source_location,
255
+ source_entry_mode,
256
+ source_id,
257
+ diff,
258
+ entry_mode,
259
+ id,
260
+ copy,
261
+ } => Event :: Rewrite {
262
+ source_location : source_location. as_ref ( ) ,
263
+ source_entry_mode : * source_entry_mode,
264
+ source_id : source_id. attach ( old_repo) ,
265
+ diff : * diff,
266
+ entry_mode : * entry_mode,
267
+ id : id. attach ( new_repo) ,
268
+ copy : * copy,
269
+ } ,
270
+ }
271
+ }
272
+ }
273
+
89
274
impl < ' a , ' old , ' new > Event < ' a , ' old , ' new > {
90
275
/// Return the current mode of this instance.
91
276
pub fn entry_mode ( & self ) -> gix_object:: tree:: EntryMode {
0 commit comments