public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: Jeff King <peff@peff•net>
To: "brian m. carlson" <sandals@crustytoothpaste•net>
Cc: git@vger•kernel.org
Subject: Re: Unexpected exit code for --help with rev-parse --parseopt
Date: Sat, 14 Mar 2026 23:14:47 -0400	[thread overview]
Message-ID: <20260315031447.GB926820@coredump.intra.peff.net> (raw)
In-Reply-To: <abYCxrEEPaI21g3H@fruit.crustytoothpaste.net>

On Sun, Mar 15, 2026 at 12:52:22AM +0000, brian m. carlson wrote:

> I use git rev-parse --parseopt to parse command-line options in various
> script.  I've noticed that it exits 129 if the options are invalid,
> which is fine, but that it also exits 129 if --help or -h are given,
> which is not.
> 
> The standard philosophy is that if the user explicitly asked for help,
> then help output should be printed to standard output (since that's what
> the user asked for) and it should exit 0, since the program fulfilled
> the user's request successfully.  If the help output is provided because
> the user provided an invalid option or argument, then the output should
> Go to standard error (since it's an error message) and the program
> should exit unsuccessfully (since it did not fulfill the user's request
> successfully).

I agree with this philosophy in general, but there's catch here with
"rev-parse --parseopt", because it's running as a separate program. It
needs to signal to the calling program that "-h" was seen, the program
should not proceed normally (because rev-parse already dumped help
output).

So if your proposal is to just exit with code 0 from rev-parse, I don't
think that works.

My first instinct is that it would have to exit with some other
well-known code, the callers would recognize that, and then exit
themselves (with code 0).

But there's a little more to the story. The output of --parseopt is meant
to be eval'd by the shell. And so when it works, we get a "set" command:

  $ git rev-parse --parseopt <input -- --output=foo
  set -- -o 'foo' --

And when there's an error, it dumps the usage text straight to stderr
and exits 129:

  $ git rev-parse --parseopt <input -- --foo
  error: unknown option `foo'
  usage: foo-cmd [<options>] <args>...
  
      Do stuff.
  
      -h, --help            show this help
      -o, --[no-]output ... output to this file
      -d, --[no-]dir ...    specify dependencies relative to this directory

But when the user asks for "-h", we get a here-doc! Like this:

  $ git rev-parse --parseopt <input -- -h
  cat <<\EOF
  usage: foo-cmd [<options>] <args>...
  
      Do stuff.
  
      -h, --help            show this help
      -o, --[no-]output ... output to this file
      -d, --[no-]dir ...    specify dependencies relative to this directory
  
  EOF

So the calling program runs that cat command. And I think what you
really want is to tack "exit 0" onto the end of that output, which would
tell the callers to exit. Something like this:

diff --git a/parse-options.c b/parse-options.c
index a676da86f5..b990f38419 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -1473,8 +1473,10 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
 	}
 	fputc('\n', outfile);
 
-	if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
+	if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL) {
 		fputs("EOF\n", outfile);
+		fputs("exit 0\n", outfile);
+	}
 
 	return PARSE_OPT_HELP;
 }

And then you don't even need to change the exit code of rev-parse itself
(since we'd never hit the "exit $?" that the caller tacks on in case of
failure). Though I think it might be reasonable to switch it to 0
anyway.

-Peff

  reply	other threads:[~2026-03-15  3:14 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-15  0:52 Unexpected exit code for --help with rev-parse --parseopt brian m. carlson
2026-03-15  3:14 ` Jeff King [this message]
2026-03-15 16:59   ` brian m. carlson
2026-03-15 18:16     ` Jeff King
2026-03-16 22:07 ` [PATCH] rev-parse: have --parseopt callers exit 0 on --help brian m. carlson
2026-03-17  0:47   ` Junio C Hamano
2026-03-17 11:59     ` brian m. carlson
2026-03-17 14:55       ` Jeff King
2026-03-17 15:07         ` Jeff King
2026-03-17 17:06         ` Junio C Hamano
2026-03-17 18:44           ` Jeff King
2026-03-18  0:24             ` brian m. carlson
2026-03-18  1:22               ` Jeff King
2026-03-18  2:45                 ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260315031447.GB926820@coredump.intra.peff.net \
    --to=peff@peff$(echo .)net \
    --cc=git@vger$(echo .)kernel.org \
    --cc=sandals@crustytoothpaste$(echo .)net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox