Ian Wienand <iwienand@xxxxxxxxxx> writes: > +* If the shell alias is the full path to a binary, it will be executed > + directly with any arguments as positional arguments. > +* If the alias contains any white-space or reserved characters, it > + will be considered an inline script and run as an argument to `sh > + -c`. > +* When running as a script, if arguments are provided to the alias > + call, Git makes them available to the process by appending "$@" to > + the alias shell command. This is not appended if arguments are not > + provided. These are not technically wrong per-se. > +** For "simple" commands, such as calling a single binary > + (e.g. `alias.myapp = !myapp --myflag1`) this will result in any > + arguments becoming additional regular positional arguments to the > + called binary, appended after any arguments specified in the aliased > + command. But the single-command script still receives the arguments in argv[], so what the alias command has to do is the same. The earlier ones that are "not technically wrong" are merely implemenation detail. In a single command case, e.g., "[alias] single = !one", you may write #!/bin/sh echo "$1" | grep "$2" in 'one' script, and "git single 1 2" will be turned into start_command: one 1 2 i.e. one receives two arguments in argv[]. It is an implementation detail that we can bypass "sh" or "-c" or "$@" If you write exactly the same thing like $ git -c 'alias=single=!one ' single 1 2 you'll instead see start_command: /bin/sh -c 'one' "$@" "one " 1 2 because the trailing SP in the alias disables the optimization to bypass a more generic 'sh -c ... "$@"' construction. What gets run is an equivalent of the reader saying $ /bin/sh -c 'one "$@"' "one " 1 2 bypassing git from the command line. What the script (one) has to write does not change at all either case. As I keep saying over multiple iterations, the above three bullet points stress too much on the minute implementation detail while failing to tell readers that the end-user alias receives the rest of the command line as arguments. > +** Care should be taken if your alias script has multiple commands > + (e.g. in a pipeline), references argument variables, or is "argument variables" -> "arguments". > + otherwise not expecting the presence of the appended `"$@"`. "otherwise not expecting" is SIMPLY BUGGY but the readers may not understand it unless you tell them that the arguments are fed to their aliased command by appending them. When you look at the implementation detail of "sh -c '... $@' - $ARGS" as something to fight against, readers would lose sight to see the crux of the problem they are trying to solve. I think it is a wrong way to frame the issue. The problem readers are solving when coming up with their own alias is this: How would one write a single-liner that can take arguments appended at the end? I think giving that to the readers upfront, i.e. "when you write an alias, you are forming a single-liner that takes arguments appended at the end", would go a long way without having them lose sight in the implementation details of "sometimes args directly come in argv[], sometimes your alias is wrapped in "sh -c" and "$@" is used. They do the same thing to feed the arguments to your script. Going back that 'one' example, if 'echo "$1" | grep "$2"' was what you wanted to run, how would you write a single-liner that does echo "$1" | grep "$2" and can take its arguments at the end? You do *not* want to see your invocation of the alias $ git single 1 2 turn into $ echo "$1" | grep "$2" 1 2 of course, and remember, "$@" is merely an implementation detail that the end-users do not need to see. Of course the simplest one-liner, if you had the "one" script already stored in the file, is to say $ one 1 2 i.e. "[alias] single = !one". But calling that a "single-liner" is cheating. You can do one of two easy things. $ sh -c 'echo "$1" | grep "$2"' - 1 2 $ e(){ echo "$1" | grep "$2"; };e 1 2 The earlier string (before "1 2" is appended) of either of these gives you "a single-liner that takes arguments at the end" that does the "echo the first one, pipe it to grep that looks for the second one", which you would make the body of the alias. If the reader understands the earlier example that stores it in a file, the former is more mechanical and straight-forward rewrite of it. The latter may be a bit more convoluted, but says the same thing in the same number of letters. HTH.