@@ -5,7 +5,7 @@ use gix::index::Entry;
5
5
use gix:: prelude:: FindExt ;
6
6
use gix:: Progress ;
7
7
use 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 } ;
9
9
10
10
pub enum Submodules {
11
11
/// display all information about submodules, including ref changes, modifications and untracked files.
@@ -48,73 +48,116 @@ pub fn show(
48
48
) ?;
49
49
let mut progress = progress. add_child ( "traverse index" ) ;
50
50
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
+ } ;
51
68
gix_status:: index_as_worktree (
52
69
index,
53
70
repo. work_dir ( )
54
71
. context ( "This operation cannot be run on a bare repository" ) ?,
55
72
& mut Printer ( out) ,
56
73
FastEq ,
74
+ Submodule ,
57
75
{
58
76
let odb = repo. objects . clone ( ) . into_arc ( ) ?;
59
77
move |id, buf| odb. find_blob ( id, buf)
60
78
} ,
61
79
& mut progress,
62
80
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,
68
87
) ?;
69
88
70
89
writeln ! ( err, "\n head -> index and untracked files aren't implemented yet" ) ?;
71
90
progress. show_throughput ( start) ;
72
91
Ok ( ( ) )
73
92
}
74
93
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
+
75
106
struct Printer < W > ( W ) ;
76
107
77
108
impl < ' index , W > gix_status:: index_as_worktree:: VisitEntry < ' index > for Printer < W >
78
109
where
79
110
W : std:: io:: Write ,
80
111
{
81
112
type ContentChange = ( ) ;
113
+ type SubmoduleStatus = ( ) ;
82
114
83
115
fn visit_entry (
84
116
& mut self ,
85
- entry : & ' index Entry ,
117
+ _entries : & ' index [ Entry ] ,
118
+ _entry : & ' index Entry ,
119
+ _entry_index : usize ,
86
120
rela_path : & ' index BStr ,
87
- change : Option < Change < Self :: ContentChange > > ,
88
- conflict : bool ,
121
+ status : EntryStatus < Self :: ContentChange > ,
89
122
) {
90
- self . visit_inner ( entry , rela_path, change , conflict ) . ok ( ) ;
123
+ self . visit_inner ( rela_path, status ) . ok ( ) ;
91
124
}
92
125
}
93
126
94
127
impl < 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}" )
109
141
}
110
142
}
111
143
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 {
113
157
// 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
+ }
120
163
}
0 commit comments