git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Weird behavior of shell variables in git aliases

From
Jeff King <peff@peff.net>
Date
Mar 22, 2011, 13:28 UTC
Message-ID
<20110322132820.GA14559@sigill.intra.peff.net>
In-Reply-To
<20110322111844.GA32446@sigill.intra.peff.net>
On Tue, Mar 22, 2011 at 07:18:44AM -0400, Jeff King wrote:
Show 25 quoted lines
> Doesn't it also break a lot of other more garden-variety aliases that
> rely on the automagic "$@", like:
> 
>   $ git config alias.log-nopager
>   !git --no-pager log
> [...]
>   $ GIT_TRACE=1 git.master log-nopager --oneline
>   trace: exec: 'git-log-nopager' '--oneline'
>   trace: run_command: 'git-log-nopager' '--oneline'
>   trace: run_command: 'git --no-pager log' '--oneline'
>   trace: exec: 'sh' '-c' 'git --no-pager log "$@"' 'git --no-pager log' '--oneline'
>   trace: built-in: git 'log' '--oneline'
>   93c7d44 foo
> 
>   $ GIT_TRACE=1 git.jch.shell-alias log-nopager --oneline
>   trace: exec: 'git-log-nopager' '--oneline'
>   trace: run_command: 'git-log-nopager' '--oneline'
>   trace: run_command: 'sh' '-c' 'git --no-pager log' '-' '--oneline'
>   trace: exec: 'sh' '-c' 'git --no-pager log' '-' '--oneline'
>   trace: built-in: git 'log'
>   commit 93c7d44635e8bb56a4fd864d024ce75a2ad4ffcf
>   Author: Jeff King <peff@peff.net>
>   Date:   Tue Mar 22 06:57:02 2011 -0400
> 
>       foo

One other solution would be to make the "$@" more magic by detecting when the alias uses positional parameters and omitting it in that case. Something like (on top of your patch):

diff --git a/git.c b/git.c
index 8d54466..1daf89c 100644
--- a/git.c
+++ b/git.c
@@ -161,6 +161,27 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
 	return handled;
 }
 
+static int alias_uses_positional_parameters(const char *s)
+{
+	while ((s = strchr(s, '$')))
+		if (s[1] == '@' || s[1] == '#' ||
+		   (s[1] >= '1' && s[1] <= '9'))
+			return 1;
+	return 0;
+}
+
+static char *alias_to_shell(const char *in)
+{
+	struct strbuf out = STRBUF_INIT;
+
+	if (alias_uses_positional_parameters(in))
+		return xstrdup(in);
+
+	strbuf_addstr(&out, in);
+	strbuf_addstr(&out, " \"$@\"");
+	return strbuf_detach(&out, NULL);
+}
+
 static int handle_alias(int *argcp, const char ***argv)
 {
 	int envchanged = 0, ret = 0, saved_errno = errno;
@@ -186,7 +207,7 @@ static int handle_alias(int *argcp, const char ***argv)
 			alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 4));
 			alias_argv[0] = "sh";
 			alias_argv[1] = "-c";
-			alias_argv[2] = alias_string + 1;
+			alias_argv[2] = alias_to_shell(alias_string + 1);
 			alias_argv[3] = "-";
 			for (i = 1; i < argc; ++i)
 				alias_argv[i + 3] = (*argv)[i];


But I think that is a little too magic for my taste. Although the false
positives ("!echo 'literal $#'") and false negatives (you want "!foo" to
_ignore_ its parameters) are pretty obscure, I would prefer to keep
things simple.

-Peff
Previous: Jeff KingNext: Lasse Makholm
Message 10 of 20 in “Weird behavior of shell variables in git aliases”
  1. Dun PealMar 21, 2011
  2. Jeff KingMar 21, 2011
  3. Junio C HamanoMar 21, 2011
  4. Junio C HamanoMar 21, 2011
  5. Lasse MakholmMar 22, 2011
  6. Jeff KingMar 22, 2011
  7. Lasse MakholmMar 22, 2011
  8. Ævar Arnfjörð BjarmasonMar 22, 2011
  9. Jeff KingMar 22, 2011
  10. Jeff KingMar 22, 2011
  11. Lasse MakholmMar 22, 2011
  12. Jeff KingMar 22, 2011
  13. Lasse MakholmMar 22, 2011
  14. Dun PealMar 22, 2011
  15. Junio C HamanoMar 22, 2011
  16. Jeff KingMar 22, 2011
  17. Lasse MakholmMar 22, 2011
  18. Junio C HamanoMar 23, 2011
  19. Junio C HamanoMar 22, 2011
  20. Junio C HamanoMar 22, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.