All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Wienand <iwienand@redhat.com>
To: git@vger.kernel.org
Cc: Ian Wienand <iwienand@redhat.com>
Subject: [PATCH] alias: pass --help through to shell alias
Date: Fri, 24 May 2024 17:04:14 +1000	[thread overview]
Message-ID: <20240524070623.1344636-2-iwienand@redhat.com> (raw)

In trying to make some aliases more consistent in an internal tool, I
implemented both -h/--help in the underlying command for a shell
alias, and was a bit surprised when "git <alias> -h" worked but "git
<alias> --help" didn't.

In the "-h" case in git.c:handle_alias() we have a little check for
"-h" which pre-prints the "<alias> is aliased to..." line and then
continues to run the alias.

However in the "--help" case we fall into the logic that turns "git
cmd --help" into "git help cmd"

help.c contains a check to just print the alias mapping if called as
"git help <alias>", but if called as "git <alias> --help", will
redirect to the help of the aliased-command.  Since a shell alias does
not have a 1:1 mapping with an internal command, the current check
prints the alias mapping and simply exits in that case (causing my
alias script "--help" command to never trigger).

I would propose that "--help" to a shell alias is passed through to
the underlying command.  This way you can write aliases that act more
like the other git commands.

To do this, we make "--help" work the same as "-h" for shell aliases.
In git.c where we check for the "--help" argument, for shell aliases
we print the aliased command as "-h" does, but then shortcut the
rewriting to "git help", so the aliased command will run and not be
sent to "git help".

Since "git <alias> --help" will not be re-written for shell aliases,
"git help" can now assume that it is being asked to help on a
git-command alias.  Thus we can remove the "is this a rewritten shell
alias" check.

A test-case is added to ensure "--help" is passed through to the
underlying command of a shell alias.

Signed-off-by: Ian Wienand <iwienand@redhat.com>
---
 builtin/help.c   |  7 +++----
 git.c            | 15 +++++++++++++++
 t/t0014-alias.sh |  8 ++++++++
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/builtin/help.c b/builtin/help.c
index 222f994f86..5e9d5edbb2 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -547,11 +547,10 @@ static const char *check_git_cmd(const char* cmd)
 		 * handle_builtin() in git.c rewrites "git cmd --help"
 		 * to "git help --exclude-guides cmd", so we can use
 		 * exclude_guides to distinguish "git cmd --help" from
-		 * "git help cmd". In the latter case, or if cmd is an
-		 * alias for a shell command, just print the alias
-		 * definition.
+		 * "git help cmd". In the latter case, just print the
+		 * alias definition.
 		 */
-		if (!exclude_guides || alias[0] == '!') {
+		if (!exclude_guides) {
 			printf_ln(_("'%s' is aliased to '%s'"), cmd, alias);
 			free(alias);
 			exit(0);
diff --git a/git.c b/git.c
index 3d8e48cf55..4c93296550 100644
--- a/git.c
+++ b/git.c
@@ -691,12 +691,27 @@ static void strip_extension(const char **argv)
 static void handle_builtin(int argc, const char **argv)
 {
 	struct strvec args = STRVEC_INIT;
+	char *alias;
 	const char *cmd;
 	struct cmd_struct *builtin;
 
 	strip_extension(argv);
 	cmd = argv[0];
 
+	/*
+	 * If this is a shell alias with --help, print it's alias
+	 * mapping to be consistent with -h and pass it through
+	 */
+	alias = alias_lookup(cmd);
+	if (alias && alias[0] == '!') {
+		if (argc > 1 && !strcmp(argv[1], "--help")) {
+			fprintf_ln(stderr, _("'%s' is aliased to '%s'"), cmd, alias);
+			free(alias);
+			return;
+		}
+		free(alias);
+	}
+
 	/* Turn "git cmd --help" into "git help --exclude-guides cmd" */
 	if (argc > 1 && !strcmp(argv[1], "--help")) {
 		int i;
diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh
index 8d3d9144c0..7b1d559420 100755
--- a/t/t0014-alias.sh
+++ b/t/t0014-alias.sh
@@ -44,4 +44,12 @@ test_expect_success 'run-command formats empty args properly' '
     test_cmp expect actual
 '
 
+test_expect_success '--help is passed to execed alias' '
+    echo "echo \"\$@\"" > exec-alias.sh &&
+    chmod +x exec-alias.sh &&
+    git config alias.exec-alias "!\"$(pwd)/exec-alias.sh\"" &&
+    GIT_TRACE=1 git exec-alias --help &> output &&
+    test_i18ngrep -- "--help" output
+'
+
 test_done
-- 
2.45.1


             reply	other threads:[~2024-05-24  7:07 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-24  7:04 Ian Wienand [this message]
2024-05-25  0:34 ` [PATCH] alias: pass --help through to shell alias Junio C Hamano
2024-05-25  1:36   ` Ian Wienand

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=20240524070623.1344636-2-iwienand@redhat.com \
    --to=iwienand@redhat.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.