@@ -203,14 +203,6 @@ impl FileStatus {
203203 matches ! ( self , FileStatus :: Untracked )
204204 }
205205
206- pub fn is_renamed ( self ) -> bool {
207- let FileStatus :: Tracked ( tracked) = self else {
208- return false ;
209- } ;
210- tracked. index_status == StatusCode :: Renamed
211- || tracked. worktree_status == StatusCode :: Renamed
212- }
213-
214206 pub fn summary ( self ) -> GitSummary {
215207 match self {
216208 FileStatus :: Ignored => GitSummary :: UNCHANGED ,
@@ -438,79 +430,34 @@ impl std::ops::Sub for GitSummary {
438430#[ derive( Clone , Debug ) ]
439431pub struct GitStatus {
440432 pub entries : Arc < [ ( RepoPath , FileStatus ) ] > ,
441- pub renamed_paths : HashMap < RepoPath , RepoPath > ,
442433}
443434
444435impl FromStr for GitStatus {
445436 type Err = anyhow:: Error ;
446437
447438 fn from_str ( s : & str ) -> Result < Self > {
448- let mut parts = s. split ( '\0' ) . peekable ( ) ;
449- let mut entries = Vec :: new ( ) ;
450- let mut renamed_paths = HashMap :: default ( ) ;
451-
452- while let Some ( entry) = parts. next ( ) {
453- if entry. is_empty ( ) {
454- continue ;
455- }
456-
457- if !matches ! ( entry. get( 2 ..3 ) , Some ( " " ) ) {
458- continue ;
459- }
460-
461- let path_or_old_path = & entry[ 3 ..] ;
462-
463- if path_or_old_path. ends_with ( '/' ) {
464- continue ;
465- }
466-
467- let status = match entry. as_bytes ( ) [ 0 ..2 ] . try_into ( ) {
468- Ok ( bytes) => match FileStatus :: from_bytes ( bytes) . log_err ( ) {
469- Some ( s) => s,
470- None => continue ,
471- } ,
472- Err ( _) => continue ,
473- } ;
474-
475- let is_rename = matches ! (
476- status,
477- FileStatus :: Tracked ( TrackedStatus {
478- index_status: StatusCode :: Renamed | StatusCode :: Copied ,
479- ..
480- } ) | FileStatus :: Tracked ( TrackedStatus {
481- worktree_status: StatusCode :: Renamed | StatusCode :: Copied ,
482- ..
483- } )
484- ) ;
485-
486- let ( old_path_str, new_path_str) = if is_rename {
487- let new_path = match parts. next ( ) {
488- Some ( new_path) if !new_path. is_empty ( ) => new_path,
489- _ => continue ,
439+ let mut entries = s
440+ . split ( '\0' )
441+ . filter_map ( |entry| {
442+ let sep = entry. get ( 2 ..3 ) ?;
443+ if sep != " " {
444+ return None ;
490445 } ;
491- ( path_or_old_path, new_path)
492- } else {
493- ( path_or_old_path, path_or_old_path)
494- } ;
495-
496- if new_path_str. ends_with ( '/' ) {
497- continue ;
498- }
499-
500- let new_path = match RelPath :: unix ( new_path_str) . log_err ( ) {
501- Some ( p) => RepoPath :: from_rel_path ( p) ,
502- None => continue ,
503- } ;
504-
505- if is_rename {
506- if let Some ( old_path_rel) = RelPath :: unix ( old_path_str) . log_err ( ) {
507- let old_path_repo = RepoPath :: from_rel_path ( old_path_rel) ;
508- renamed_paths. insert ( new_path. clone ( ) , old_path_repo) ;
446+ let path = & entry[ 3 ..] ;
447+ // The git status output includes untracked directories as well as untracked files.
448+ // We do our own processing to compute the "summary" status of each directory,
449+ // so just skip any directories in the output, since they'll otherwise interfere
450+ // with our handling of nested repositories.
451+ if path. ends_with ( '/' ) {
452+ return None ;
509453 }
510- }
511-
512- entries. push ( ( new_path, status) ) ;
513- }
454+ let status = entry. as_bytes ( ) [ 0 ..2 ] . try_into ( ) . unwrap ( ) ;
455+ let status = FileStatus :: from_bytes ( status) . log_err ( ) ?;
456+ // git-status outputs `/`-delimited repo paths, even on Windows.
457+ let path = RepoPath :: from_rel_path ( RelPath :: unix ( path) . log_err ( ) ?) ;
458+ Some ( ( path, status) )
459+ } )
460+ . collect :: < Vec < _ > > ( ) ;
514461 entries. sort_unstable_by ( |( a, _) , ( b, _) | a. cmp ( b) ) ;
515462 // When a file exists in HEAD, is deleted in the index, and exists again in the working copy,
516463 // git produces two lines for it, one reading `D ` (deleted in index, unmodified in working copy)
@@ -534,7 +481,6 @@ impl FromStr for GitStatus {
534481 } ) ;
535482 Ok ( Self {
536483 entries : entries. into ( ) ,
537- renamed_paths,
538484 } )
539485 }
540486}
@@ -543,7 +489,6 @@ impl Default for GitStatus {
543489 fn default ( ) -> Self {
544490 Self {
545491 entries : Arc :: new ( [ ] ) ,
546- renamed_paths : HashMap :: default ( ) ,
547492 }
548493 }
549494}
0 commit comments