@@ -2,8 +2,7 @@ use std::io;
22use std:: marker:: PhantomData ;
33use std:: path:: Path ;
44
5- use crate :: index:: status:: diff:: { self , Diff } ;
6- use crate :: index:: status:: { Collector , Status } ;
5+ use crate :: index:: status:: { content, Change , Collector , ContentComparison } ;
76use crate :: { fs, read} ;
87use bstr:: BStr ;
98use filetime:: FileTime ;
@@ -62,12 +61,18 @@ impl Default for Options {
6261 }
6362}
6463
65- /// Calculates the status of worktree
66- pub fn status < ' index , T : Send > (
64+ /// Calculates the changes that need to be applied to an index to obtain a
65+ /// worktree. Note that this isn't technically quite what this function does
66+ /// as this also provides some additional information (whether a file has
67+ /// conflicts) and files that were added with `git add` are shown as a special
68+ /// changes despite not technically requiring a change to the index (since `gid
69+ /// add` already added the file to the index) but the naming matches the intuition
70+ /// of a git user (and matches `git status`/git diff`)
71+ pub fn changes_to_obtain < ' index , T : Send > (
6772 index : & ' index mut index:: State ,
6873 worktree : & Path ,
69- collector : & mut impl Collector < ' index , Diff = T > ,
70- diff : & impl Diff < Output = T > ,
74+ collector : & mut impl Collector < ' index , ContentChange = T > ,
75+ diff : & impl ContentComparison < Output = T > ,
7176 options : Options ,
7277) -> Result < ( ) , Error > {
7378 // the order is absoluty critical here
@@ -116,13 +121,13 @@ struct State<'a, 'b> {
116121 options : & ' a Options ,
117122}
118123
119- type StatusResult < ' index , T > = Result < ( & ' index index:: Entry , & ' index BStr , Status < T > , bool ) , Error > ;
124+ type StatusResult < ' index , T > = Result < ( & ' index index:: Entry , & ' index BStr , Option < Change < T > > , bool ) , Error > ;
120125
121126impl < ' index > State < ' _ , ' index > {
122127 fn process < T > (
123128 & mut self ,
124129 entry : & ' index mut index:: Entry ,
125- diff : & impl Diff < Output = T > ,
130+ diff : & impl ContentComparison < Output = T > ,
126131 ) -> Option < StatusResult < ' index , T > > {
127132 let conflict = match entry. stage ( ) {
128133 0 => false ,
@@ -146,8 +151,8 @@ impl<'index> State<'_, 'index> {
146151 & mut self ,
147152 entry : & mut index:: Entry ,
148153 git_path : & BStr ,
149- diff : & impl Diff < Output = T > ,
150- ) -> Result < Status < T > , Error > {
154+ diff : & impl ContentComparison < Output = T > ,
155+ ) -> Result < Option < Change < T > > , Error > {
151156 // TODO fs caache
152157 let worktree_path = path:: try_from_bstr ( git_path) . map_err ( |_| Error :: IllformedUtf8 ) ?;
153158 let worktree_path = self . worktree . join ( worktree_path) ;
@@ -163,24 +168,24 @@ impl<'index> State<'_, 'index> {
163168 // TODO: submodules:
164169 // if entry.mode.contains(Mode::COMMIT) &&
165170 // resolve_gitlink_ref(ce->name, "HEAD", &sub))
166- return Ok ( Status :: Removed ) ;
171+ return Ok ( Some ( Change :: Removed ) ) ;
167172 }
168173 Ok ( metadata) => metadata,
169- Err ( err) if err. kind ( ) == io:: ErrorKind :: NotFound => return Ok ( Status :: Removed ) ,
174+ Err ( err) if err. kind ( ) == io:: ErrorKind :: NotFound => return Ok ( Some ( Change :: Removed ) ) ,
170175 Err ( err) => {
171176 return Err ( err. into ( ) ) ;
172177 }
173178 } ;
174179 if self . options . check_added && entry. flags . contains ( index:: entry:: Flags :: INTENT_TO_ADD ) {
175- return Ok ( Status :: Added ) ;
180+ return Ok ( Some ( Change :: Added ) ) ;
176181 }
177182 let new_stat = index:: entry:: Stat :: from_fs ( & metadata) ?;
178183 let executable_bit_changed =
179184 match entry
180185 . mode
181186 . change_to_match_fs ( & metadata, self . options . fs . symlink , self . options . fs . executable_bit )
182187 {
183- Some ( index:: entry:: mode:: Change :: Type { .. } ) => return Ok ( Status :: TypeChange ) ,
188+ Some ( index:: entry:: mode:: Change :: Type { .. } ) => return Ok ( Some ( Change :: TypeChange ) ) ,
184189 Some ( index:: entry:: mode:: Change :: ExecutableBit ) => true ,
185190 None => false ,
186191 } ;
@@ -202,7 +207,7 @@ impl<'index> State<'_, 'index> {
202207 {
203208 racy_clean = new_stat. is_racy ( self . timestamp , self . options . stat ) ;
204209 if !racy_clean {
205- return Ok ( Status :: Unchanged ) ;
210+ return Ok ( None ) ;
206211 }
207212 }
208213
@@ -212,22 +217,22 @@ impl<'index> State<'_, 'index> {
212217 entry,
213218 options : self . options ,
214219 } ;
215- let diff = diff. content_changed :: < Error > ( entry, metadata. len ( ) as usize , file, |_| Ok ( & [ ] ) ) ?;
220+ let content_change = diff. compare_blob :: < Error > ( entry, metadata. len ( ) as usize , file, |_| Ok ( & [ ] ) ) ?;
216221 // this file is racy clean! Set the size to 0 so we keep detecting this
217222 // as the file is updated
218- if diff . is_some ( ) && racy_clean {
223+ if content_change . is_some ( ) && racy_clean {
219224 entry. stat . size = 0 ;
220225 }
221- if diff . is_some ( ) || executable_bit_changed {
222- Ok ( Status :: Modified {
226+ if content_change . is_some ( ) || executable_bit_changed {
227+ Ok ( Some ( Change :: Modified {
223228 executable_bit_changed,
224- diff ,
225- } )
229+ content_change ,
230+ } ) )
226231 } else {
227232 // don't diff against this file next time since
228233 // we know the file is unchanged
229234 entry. stat = new_stat;
230- Ok ( Status :: Unchanged )
235+ Ok ( None )
231236 }
232237 }
233238}
@@ -237,7 +242,7 @@ struct Reducer<'a, 'index, T: Collector<'index>> {
237242 phantom : PhantomData < fn ( & ' index ( ) ) > ,
238243}
239244
240- impl < ' index , T , C : Collector < ' index , Diff = T > > Reduce for Reducer < ' _ , ' index , C > {
245+ impl < ' index , T , C : Collector < ' index , ContentChange = T > > Reduce for Reducer < ' _ , ' index , C > {
241246 type Input = Vec < StatusResult < ' index , T > > ;
242247
243248 type FeedProduce = ( ) ;
@@ -248,8 +253,8 @@ impl<'index, T, C: Collector<'index, Diff = T>> Reduce for Reducer<'_, 'index, C
248253
249254 fn feed ( & mut self , items : Self :: Input ) -> Result < Self :: FeedProduce , Self :: Error > {
250255 for item in items {
251- let ( entry, path, status , conflict) = item?;
252- self . collector . visit_entry ( entry, path, status , conflict) ;
256+ let ( entry, path, change , conflict) = item?;
257+ self . collector . visit_entry ( entry, path, change , conflict) ;
253258 }
254259 Ok ( ( ) )
255260 }
@@ -265,7 +270,7 @@ struct WorktreeFile<'a> {
265270 options : & ' a Options ,
266271}
267272
268- impl < ' a > diff :: LazyBlob < ' a , Error > for WorktreeFile < ' a > {
273+ impl < ' a > content :: LazyBlob < ' a , Error > for WorktreeFile < ' a > {
269274 fn read ( self ) -> Result < & ' a [ u8 ] , Error > {
270275 let res = read:: data_to_buf_with_meta (
271276 self . path ,
0 commit comments