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