rhg: support `status --print0`
authorArseniy Alekseyev <aalekseyev@janestreet.com>
Thu, 06 Apr 2023 11:41:51 +0100
changeset 50461 98fc949bec14
parent 50460 f0d2b18f0274
child 50462 59fda8516774
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.
rust/rhg/src/commands/status.rs
tests/test-status.t
--- a/rust/rhg/src/commands/status.rs	Thu Mar 30 22:22:44 2023 +0200
+++ b/rust/rhg/src/commands/status.rs	Thu Apr 06 11:41:51 2023 +0100
@@ -111,6 +111,13 @@
                 .long("copies"),
         )
         .arg(
+            Arg::new("print0")
+                .help("end filenames with NUL, for use with xargs")
+                .short('0')
+                .action(clap::ArgAction::SetTrue)
+                .long("print0"),
+        )
+        .arg(
             Arg::new("no-status")
                 .help("hide status prefix")
                 .short('n')
@@ -213,10 +220,11 @@
     let config = invocation.config;
     let args = invocation.subcommand_args;
 
-    // TODO add `!args.get_flag("print0") &&` when we support `print0`
+    let print0 = args.get_flag("print0");
     let verbose = args.get_flag("verbose")
         || config.get_bool(b"ui", b"verbose")?
         || config.get_bool(b"commands", b"status.verbose")?;
+    let verbose = verbose && !print0;
 
     let all = args.get_flag("all");
     let display_states = if all {
@@ -363,6 +371,7 @@
             } else {
                 None
             },
+            print0,
         };
         if display_states.modified {
             output.display(b"M ", "status.modified", ds_status.modified)?;
@@ -527,6 +536,7 @@
     ui: &'a Ui,
     no_status: bool,
     relativize: Option<RelativizePaths>,
+    print0: bool,
 }
 
 impl DisplayStatusPaths<'_> {
@@ -555,12 +565,15 @@
             if !self.no_status {
                 self.ui.write_stdout_labelled(status_prefix, label)?
             }
-            self.ui
-                .write_stdout_labelled(&format_bytes!(b"{}\n", path), label)?;
+            let linebreak = if self.print0 { b"\x00" } else { b"\n" };
+            self.ui.write_stdout_labelled(
+                &format_bytes!(b"{}{}", path, linebreak),
+                label,
+            )?;
             if let Some(source) = copy_source {
                 let label = "status.copied";
                 self.ui.write_stdout_labelled(
-                    &format_bytes!(b"  {}\n", source.as_bytes()),
+                    &format_bytes!(b"  {}{}", source.as_bytes(), linebreak),
                     label,
                 )?
             }
--- a/tests/test-status.t	Thu Mar 30 22:22:44 2023 +0200
+++ b/tests/test-status.t	Thu Apr 06 11:41:51 2023 +0100
@@ -246,6 +246,11 @@
   ! deleted
   ? unknown
 
+hg status -0:
+
+  $ hg status -0 --config rhg.on-unsupported=abort
+  A added\x00A copied\x00R removed\x00! deleted\x00? unknown\x00 (no-eol) (esc)
+
 hg status -A:
 
   $ hg status -A