1
- use crate :: index_as_worktree:: EntryStatus ;
1
+ use crate :: index_as_worktree:: { Change , EntryStatus } ;
2
2
use bstr:: { BStr , ByteSlice } ;
3
3
use std:: sync:: atomic:: AtomicBool ;
4
4
@@ -141,6 +141,58 @@ pub enum Entry<'index, ContentChange, SubmoduleStatus> {
141
141
} ,
142
142
}
143
143
144
+ /// An easy to grasp summary of the changes of the worktree compared to the index.
145
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq , PartialOrd , Ord , Hash ) ]
146
+ pub enum Summary {
147
+ /// An entry exists in the index but doesn't in the worktree.
148
+ Removed ,
149
+ /// A file exists in the worktree but doesn't have a corresponding entry in the index.
150
+ ///
151
+ /// In a `git status`, this would be an untracked file.
152
+ Added ,
153
+ /// A file or submodule was modified, compared to the state recorded in the index.
154
+ /// On Unix, the change of executable bit also counts as modification.
155
+ ///
156
+ /// If the modification is a submodule, it could also stem from various other factors, like
157
+ /// having modified or untracked files, or changes in the index.
158
+ Modified ,
159
+ /// The type of the entry in the worktree changed compared to the index.
160
+ ///
161
+ /// This can happen if a file in the worktree now is a directory, or a symlink, for example.
162
+ TypeChange ,
163
+ /// A match between an entry in the index and a differently named file in the worktree was detected,
164
+ /// considering the index the source of a rename operation, and the worktree file the destination.
165
+ ///
166
+ /// Note that the renamed file may also have been modified, but is considered similar enough.
167
+ ///
168
+ /// To obtain this state, rewrite-tracking must have been enabled, as otherwise the source would be
169
+ /// considered `Removed` and the destination would be considered `Added`.
170
+ Renamed ,
171
+ /// A match between an entry in the index and a differently named file in the worktree was detected,
172
+ /// considering the index the source of the copy of a worktree file.
173
+ ///
174
+ /// Note that the copied file may also have been modified, but is considered similar enough.
175
+ ///
176
+ /// To obtain this state, rewrite-and-copy-tracking must have been enabled, as otherwise the source would be
177
+ /// considered `Removed` and the destination would be considered `Added`.
178
+ Copied ,
179
+ /// An index entry with a corresponding worktree file that corresponds to an untracked worktree
180
+ /// file marked with `git add --intent-to-add`.
181
+ ///
182
+ /// This means it's not available in the object database yet even though now an entry exists
183
+ /// that represents the worktree file.
184
+ /// The entry represents the promise of adding a new file, no matter the actual stat or content.
185
+ /// Effectively this means nothing changed.
186
+ /// This also means the file is still present, and that no detailed change checks were performed.
187
+ IntentToAdd ,
188
+ /// Describes a conflicting entry in the index, which also means that
189
+ /// no further comparison to the worktree file was performed.
190
+ ///
191
+ /// As this variant only describes the state of the index, the corresponding worktree file may
192
+ /// or may not exist.
193
+ Conflict ,
194
+ }
195
+
144
196
/// Access
145
197
impl < ContentChange , SubmoduleStatus > RewriteSource < ' _ , ContentChange , SubmoduleStatus > {
146
198
/// The repository-relative path of this source.
@@ -156,6 +208,47 @@ impl<ContentChange, SubmoduleStatus> RewriteSource<'_, ContentChange, SubmoduleS
156
208
157
209
/// Access
158
210
impl < ContentChange , SubmoduleStatus > Entry < ' _ , ContentChange , SubmoduleStatus > {
211
+ /// Return a summary of the entry as digest of its status, or `None` if this entry is
212
+ /// created from the directory walk and is *not untracked*, or if it is merely to communicate
213
+ /// a needed update to the index entry.
214
+ pub fn summary ( & self ) -> Option < Summary > {
215
+ Some ( match self {
216
+ Entry :: Modification {
217
+ status : EntryStatus :: Conflict ( _) ,
218
+ ..
219
+ } => Summary :: Conflict ,
220
+ Entry :: Modification {
221
+ status : EntryStatus :: IntentToAdd ,
222
+ ..
223
+ } => Summary :: IntentToAdd ,
224
+ Entry :: Modification {
225
+ status : EntryStatus :: NeedsUpdate ( _) ,
226
+ ..
227
+ } => return None ,
228
+ Entry :: Modification {
229
+ status : EntryStatus :: Change ( change) ,
230
+ ..
231
+ } => match change {
232
+ Change :: SubmoduleModification ( _) | Change :: Modification { .. } => Summary :: Modified ,
233
+ Change :: Type => Summary :: TypeChange ,
234
+ Change :: Removed => Summary :: Removed ,
235
+ } ,
236
+ Entry :: DirectoryContents { entry, .. } => {
237
+ if matches ! ( entry. status, gix_dir:: entry:: Status :: Untracked ) {
238
+ Summary :: Added
239
+ } else {
240
+ return None ;
241
+ }
242
+ }
243
+ Entry :: Rewrite { copy, .. } => {
244
+ if * copy {
245
+ Summary :: Copied
246
+ } else {
247
+ Summary :: Renamed
248
+ }
249
+ }
250
+ } )
251
+ }
159
252
/// The repository-relative path at which the source of a rewrite is located.
160
253
///
161
254
/// If this isn't a rewrite, the path is the location of the entry itself.
0 commit comments