Mercurial > hg
comparison rust/rhg/src/commands/status.rs @ 50427:98fc949bec14
rhg: support `status --print0`
This seems very easy to support, and useful because it makes it possible
to parse the [hg status] output even if the user creates files
with '\n' characters by accident.
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Thu, 06 Apr 2023 11:41:51 +0100 |
parents | a6b8b1ab9116 |
children | f57f5ab0e220 |
comparison
equal
deleted
inserted
replaced
50426:f0d2b18f0274 | 50427:98fc949bec14 |
---|---|
109 .short('C') | 109 .short('C') |
110 .action(clap::ArgAction::SetTrue) | 110 .action(clap::ArgAction::SetTrue) |
111 .long("copies"), | 111 .long("copies"), |
112 ) | 112 ) |
113 .arg( | 113 .arg( |
114 Arg::new("print0") | |
115 .help("end filenames with NUL, for use with xargs") | |
116 .short('0') | |
117 .action(clap::ArgAction::SetTrue) | |
118 .long("print0"), | |
119 ) | |
120 .arg( | |
114 Arg::new("no-status") | 121 Arg::new("no-status") |
115 .help("hide status prefix") | 122 .help("hide status prefix") |
116 .short('n') | 123 .short('n') |
117 .action(clap::ArgAction::SetTrue) | 124 .action(clap::ArgAction::SetTrue) |
118 .long("no-status"), | 125 .long("no-status"), |
211 | 218 |
212 let ui = invocation.ui; | 219 let ui = invocation.ui; |
213 let config = invocation.config; | 220 let config = invocation.config; |
214 let args = invocation.subcommand_args; | 221 let args = invocation.subcommand_args; |
215 | 222 |
216 // TODO add `!args.get_flag("print0") &&` when we support `print0` | 223 let print0 = args.get_flag("print0"); |
217 let verbose = args.get_flag("verbose") | 224 let verbose = args.get_flag("verbose") |
218 || config.get_bool(b"ui", b"verbose")? | 225 || config.get_bool(b"ui", b"verbose")? |
219 || config.get_bool(b"commands", b"status.verbose")?; | 226 || config.get_bool(b"commands", b"status.verbose")?; |
227 let verbose = verbose && !print0; | |
220 | 228 |
221 let all = args.get_flag("all"); | 229 let all = args.get_flag("all"); |
222 let display_states = if all { | 230 let display_states = if all { |
223 // TODO when implementing `--quiet`: it excludes clean files | 231 // TODO when implementing `--quiet`: it excludes clean files |
224 // from `--all` | 232 // from `--all` |
361 relativize: if relative_paths { | 369 relativize: if relative_paths { |
362 Some(RelativizePaths::new(repo)?) | 370 Some(RelativizePaths::new(repo)?) |
363 } else { | 371 } else { |
364 None | 372 None |
365 }, | 373 }, |
374 print0, | |
366 }; | 375 }; |
367 if display_states.modified { | 376 if display_states.modified { |
368 output.display(b"M ", "status.modified", ds_status.modified)?; | 377 output.display(b"M ", "status.modified", ds_status.modified)?; |
369 } | 378 } |
370 if display_states.added { | 379 if display_states.added { |
525 | 534 |
526 struct DisplayStatusPaths<'a> { | 535 struct DisplayStatusPaths<'a> { |
527 ui: &'a Ui, | 536 ui: &'a Ui, |
528 no_status: bool, | 537 no_status: bool, |
529 relativize: Option<RelativizePaths>, | 538 relativize: Option<RelativizePaths>, |
539 print0: bool, | |
530 } | 540 } |
531 | 541 |
532 impl DisplayStatusPaths<'_> { | 542 impl DisplayStatusPaths<'_> { |
533 // Probably more elegant to use a Deref or Borrow trait rather than | 543 // Probably more elegant to use a Deref or Borrow trait rather than |
534 // harcode HgPathBuf, but probably not really useful at this point | 544 // harcode HgPathBuf, but probably not really useful at this point |
553 // in order to stream to stdout instead of allocating an | 563 // in order to stream to stdout instead of allocating an |
554 // itermediate `Vec<u8>`. | 564 // itermediate `Vec<u8>`. |
555 if !self.no_status { | 565 if !self.no_status { |
556 self.ui.write_stdout_labelled(status_prefix, label)? | 566 self.ui.write_stdout_labelled(status_prefix, label)? |
557 } | 567 } |
558 self.ui | 568 let linebreak = if self.print0 { b"\x00" } else { b"\n" }; |
559 .write_stdout_labelled(&format_bytes!(b"{}\n", path), label)?; | 569 self.ui.write_stdout_labelled( |
570 &format_bytes!(b"{}{}", path, linebreak), | |
571 label, | |
572 )?; | |
560 if let Some(source) = copy_source { | 573 if let Some(source) = copy_source { |
561 let label = "status.copied"; | 574 let label = "status.copied"; |
562 self.ui.write_stdout_labelled( | 575 self.ui.write_stdout_labelled( |
563 &format_bytes!(b" {}\n", source.as_bytes()), | 576 &format_bytes!(b" {}{}", source.as_bytes(), linebreak), |
564 label, | 577 label, |
565 )? | 578 )? |
566 } | 579 } |
567 } | 580 } |
568 Ok(()) | 581 Ok(()) |