@@ -5,7 +5,7 @@ use gix::index::Entry;
55use gix:: prelude:: FindExt ;
66use gix:: Progress ;
77use gix_status:: index_as_worktree:: traits:: FastEq ;
8- use gix_status:: index_as_worktree:: Change ;
8+ use gix_status:: index_as_worktree:: { Change , Conflict , EntryStatus } ;
99
1010pub enum Submodules {
1111 /// display all information about submodules, including ref changes, modifications and untracked files.
@@ -48,73 +48,116 @@ pub fn show(
4848 ) ?;
4949 let mut progress = progress. add_child ( "traverse index" ) ;
5050 let start = std:: time:: Instant :: now ( ) ;
51+ let options = gix_status:: index_as_worktree:: Options {
52+ fs : repo. filesystem_options ( ) ?,
53+ thread_limit,
54+ stat : repo. stat_options ( ) ?,
55+ attributes : match repo
56+ . attributes_only (
57+ index,
58+ gix:: worktree:: stack:: state:: attributes:: Source :: WorktreeThenIdMapping ,
59+ ) ?
60+ . detach ( )
61+ . state_mut ( )
62+ {
63+ gix:: worktree:: stack:: State :: AttributesStack ( attrs) => std:: mem:: take ( attrs) ,
64+ // TODO: this should be nicer by creating attributes directly, but it's a private API
65+ _ => unreachable ! ( "state must be attributes stack only" ) ,
66+ } ,
67+ } ;
5168 gix_status:: index_as_worktree (
5269 index,
5370 repo. work_dir ( )
5471 . context ( "This operation cannot be run on a bare repository" ) ?,
5572 & mut Printer ( out) ,
5673 FastEq ,
74+ Submodule ,
5775 {
5876 let odb = repo. objects . clone ( ) . into_arc ( ) ?;
5977 move |id, buf| odb. find_blob ( id, buf)
6078 } ,
6179 & mut progress,
6280 pathspec. detach ( ) ?,
63- gix_status:: index_as_worktree:: Options {
64- fs : repo. filesystem_options ( ) ?,
65- thread_limit,
66- stat : repo. stat_options ( ) ?,
67- } ,
81+ repo. filter_pipeline ( Some ( gix:: hash:: ObjectId :: empty_tree ( repo. object_hash ( ) ) ) ) ?
82+ . 0
83+ . into_parts ( )
84+ . 0 ,
85+ & gix:: interrupt:: IS_INTERRUPTED ,
86+ options,
6887 ) ?;
6988
7089 writeln ! ( err, "\n head -> index and untracked files aren't implemented yet" ) ?;
7190 progress. show_throughput ( start) ;
7291 Ok ( ( ) )
7392}
7493
94+ #[ derive( Clone ) ]
95+ struct Submodule ;
96+
97+ impl gix_status:: index_as_worktree:: traits:: SubmoduleStatus for Submodule {
98+ type Output = ( ) ;
99+ type Error = std:: convert:: Infallible ;
100+
101+ fn status ( & mut self , _entry : & Entry , _rela_path : & BStr ) -> Result < Option < Self :: Output > , Self :: Error > {
102+ Ok ( None )
103+ }
104+ }
105+
75106struct Printer < W > ( W ) ;
76107
77108impl < ' index , W > gix_status:: index_as_worktree:: VisitEntry < ' index > for Printer < W >
78109where
79110 W : std:: io:: Write ,
80111{
81112 type ContentChange = ( ) ;
113+ type SubmoduleStatus = ( ) ;
82114
83115 fn visit_entry (
84116 & mut self ,
85- entry : & ' index Entry ,
117+ _entries : & ' index [ Entry ] ,
118+ _entry : & ' index Entry ,
119+ _entry_index : usize ,
86120 rela_path : & ' index BStr ,
87- change : Option < Change < Self :: ContentChange > > ,
88- conflict : bool ,
121+ status : EntryStatus < Self :: ContentChange > ,
89122 ) {
90- self . visit_inner ( entry , rela_path, change , conflict ) . ok ( ) ;
123+ self . visit_inner ( rela_path, status ) . ok ( ) ;
91124 }
92125}
93126
94127impl < W : std:: io:: Write > Printer < W > {
95- fn visit_inner (
96- & mut self ,
97- _entry : & Entry ,
98- rela_path : & BStr ,
99- change : Option < Change < ( ) > > ,
100- conflict : bool ,
101- ) -> anyhow:: Result < ( ) > {
102- if let Some ( change) = conflict
103- . then_some ( 'U' )
104- . or_else ( || change. as_ref ( ) . and_then ( change_to_char) )
105- {
106- writeln ! ( & mut self . 0 , "{change} {rela_path}" ) ?;
107- }
108- Ok ( ( ) )
128+ fn visit_inner ( & mut self , rela_path : & BStr , status : EntryStatus < ( ) > ) -> std:: io:: Result < ( ) > {
129+ let char_storage;
130+ let status = match status {
131+ EntryStatus :: Conflict ( conflict) => as_str ( conflict) ,
132+ EntryStatus :: Change ( change) => {
133+ char_storage = change_to_char ( & change) ;
134+ std:: str:: from_utf8 ( std:: slice:: from_ref ( & char_storage) ) . expect ( "valid ASCII" )
135+ }
136+ EntryStatus :: NeedsUpdate ( _) => return Ok ( ( ) ) ,
137+ EntryStatus :: IntentToAdd => "A" ,
138+ } ;
139+
140+ writeln ! ( & mut self . 0 , "{status: >3} {rela_path}" )
109141 }
110142}
111143
112- fn change_to_char ( change : & Change < ( ) > ) -> Option < char > {
144+ fn as_str ( c : Conflict ) -> & ' static str {
145+ match c {
146+ Conflict :: BothDeleted => "DD" ,
147+ Conflict :: AddedByUs => "AU" ,
148+ Conflict :: DeletedByThem => "UD" ,
149+ Conflict :: AddedByThem => "UA" ,
150+ Conflict :: DeletedByUs => "DU" ,
151+ Conflict :: BothAdded => "AA" ,
152+ Conflict :: BothModified => "UU" ,
153+ }
154+ }
155+
156+ fn change_to_char ( change : & Change < ( ) > ) -> u8 {
113157 // Known status letters: https://github.com/git/git/blob/6807fcfedab84bc8cd0fbf721bc13c4e68cda9ae/diff.h#L613
114- Some ( match change {
115- Change :: Removed => 'D' ,
116- Change :: Type => 'T' ,
117- Change :: Modification { .. } => 'M' ,
118- Change :: IntentToAdd => return None ,
119- } )
158+ match change {
159+ Change :: Removed => b'D' ,
160+ Change :: Type => b'T' ,
161+ Change :: SubmoduleModification ( _) | Change :: Modification { .. } => b'M' ,
162+ }
120163}
0 commit comments