Mercurial > hg
comparison rust/rhg/src/commands/status.rs @ 47321:62225f9da938
rhg: Sort `rhg status` output correctly
* The relative order of states is:
modified, added, removed, deleted, unknown, ignored, clean
* Files in the same state should be sorted by name, regardless of whether
or not the were in "unsure" state based on metadata alone.
Differential Revision: https://phab.mercurial-scm.org/D10765
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Sat, 22 May 2021 17:32:09 +0200 |
parents | 9c6b458a08e1 |
children | 1760de72a992 |
comparison
equal
deleted
inserted
replaced
47320:a43d256c041a | 47321:62225f9da938 |
---|---|
179 list_unknown: display_states.unknown, | 179 list_unknown: display_states.unknown, |
180 list_ignored: display_states.ignored, | 180 list_ignored: display_states.ignored, |
181 collect_traversed_dirs: false, | 181 collect_traversed_dirs: false, |
182 }; | 182 }; |
183 let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded | 183 let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded |
184 let (ds_status, pattern_warnings) = hg::status( | 184 let (mut ds_status, pattern_warnings) = hg::status( |
185 &dmap, | 185 &dmap, |
186 &AlwaysMatcher, | 186 &AlwaysMatcher, |
187 repo.working_directory_path().to_owned(), | 187 repo.working_directory_path().to_owned(), |
188 vec![ignore_file], | 188 vec![ignore_file], |
189 options, | 189 options, |
199 info!( | 199 info!( |
200 "Files to be rechecked by retrieval from filelog: {:?}", | 200 "Files to be rechecked by retrieval from filelog: {:?}", |
201 &ds_status.unsure | 201 &ds_status.unsure |
202 ); | 202 ); |
203 } | 203 } |
204 // TODO check ordering to match `hg status` output. | 204 if !ds_status.unsure.is_empty() |
205 // (this is as in `hg help status`) | 205 && (display_states.modified || display_states.clean) |
206 if display_states.modified { | 206 { |
207 display_status_paths(ui, &(ds_status.modified), b"M")?; | |
208 } | |
209 if !ds_status.unsure.is_empty() { | |
210 let p1: Node = parents | 207 let p1: Node = parents |
211 .expect( | 208 .expect( |
212 "Dirstate with no parents should not list any file to | 209 "Dirstate with no parents should not list any file to |
213 be rechecked for modifications", | 210 be rechecked for modifications", |
214 ) | 211 ) |
215 .p1 | 212 .p1 |
216 .into(); | 213 .into(); |
217 let p1_hex = format!("{:x}", p1); | 214 let p1_hex = format!("{:x}", p1); |
218 let mut rechecked_modified: Vec<HgPathCow> = Vec::new(); | |
219 let mut rechecked_clean: Vec<HgPathCow> = Vec::new(); | |
220 for to_check in ds_status.unsure { | 215 for to_check in ds_status.unsure { |
221 if cat_file_is_modified(repo, &to_check, &p1_hex)? { | 216 if cat_file_is_modified(repo, &to_check, &p1_hex)? { |
222 rechecked_modified.push(to_check); | 217 if display_states.modified { |
218 ds_status.modified.push(to_check); | |
219 } | |
223 } else { | 220 } else { |
224 rechecked_clean.push(to_check); | 221 if display_states.clean { |
222 ds_status.clean.push(to_check); | |
223 } | |
225 } | 224 } |
226 } | 225 } |
227 if display_states.modified { | 226 } |
228 display_status_paths(ui, &rechecked_modified, b"M")?; | 227 if display_states.modified { |
229 } | 228 display_status_paths(ui, &mut ds_status.modified, b"M")?; |
230 if display_states.clean { | |
231 display_status_paths(ui, &rechecked_clean, b"C")?; | |
232 } | |
233 } | 229 } |
234 if display_states.added { | 230 if display_states.added { |
235 display_status_paths(ui, &(ds_status.added), b"A")?; | 231 display_status_paths(ui, &mut ds_status.added, b"A")?; |
232 } | |
233 if display_states.removed { | |
234 display_status_paths(ui, &mut ds_status.removed, b"R")?; | |
235 } | |
236 if display_states.deleted { | |
237 display_status_paths(ui, &mut ds_status.deleted, b"!")?; | |
238 } | |
239 if display_states.unknown { | |
240 display_status_paths(ui, &mut ds_status.unknown, b"?")?; | |
241 } | |
242 if display_states.ignored { | |
243 display_status_paths(ui, &mut ds_status.ignored, b"I")?; | |
236 } | 244 } |
237 if display_states.clean { | 245 if display_states.clean { |
238 display_status_paths(ui, &(ds_status.clean), b"C")?; | 246 display_status_paths(ui, &mut ds_status.clean, b"C")?; |
239 } | |
240 if display_states.removed { | |
241 display_status_paths(ui, &(ds_status.removed), b"R")?; | |
242 } | |
243 if display_states.deleted { | |
244 display_status_paths(ui, &(ds_status.deleted), b"!")?; | |
245 } | |
246 if display_states.unknown { | |
247 display_status_paths(ui, &(ds_status.unknown), b"?")?; | |
248 } | |
249 if display_states.ignored { | |
250 display_status_paths(ui, &(ds_status.ignored), b"I")?; | |
251 } | 247 } |
252 Ok(()) | 248 Ok(()) |
253 } | 249 } |
254 | 250 |
255 // Probably more elegant to use a Deref or Borrow trait rather than | 251 // Probably more elegant to use a Deref or Borrow trait rather than |
256 // harcode HgPathBuf, but probably not really useful at this point | 252 // harcode HgPathBuf, but probably not really useful at this point |
257 fn display_status_paths( | 253 fn display_status_paths( |
258 ui: &Ui, | 254 ui: &Ui, |
259 paths: &[HgPathCow], | 255 paths: &mut [HgPathCow], |
260 status_prefix: &[u8], | 256 status_prefix: &[u8], |
261 ) -> Result<(), CommandError> { | 257 ) -> Result<(), CommandError> { |
258 paths.sort_unstable(); | |
262 for path in paths { | 259 for path in paths { |
263 // Same TODO as in commands::root | 260 // Same TODO as in commands::root |
264 let bytes: &[u8] = path.as_bytes(); | 261 let bytes: &[u8] = path.as_bytes(); |
265 // TODO optim, probably lots of unneeded copies here, especially | 262 // TODO optim, probably lots of unneeded copies here, especially |
266 // if out stream is buffered | 263 // if out stream is buffered |