Hacker News new | ask | show | jobs
by varl 2048 days ago
I'm not entirely sure, but `:` means "true" in bash, and if I omit it, something like this happens:

  $ git config alias.foo '! echo "$1";'
  $ git foo bar
  bar
  echo "$1";: bar: command not found
Whereas if I end with `; :` then it works as expected:

  $ git config alias.foo '! echo "$1"; :'
  $ git foo bar
  bar
It seems to execute the last argument (`bar`) as a command without the `:` at the end, and I don't have a `bar` command on my PATH so it angrily fails with exit code 127. If it instead executes `:` however, that will make it happily exit with 0.

It seems to be a Git alias quirk, but I may be incorrect here.

1 comments

Seems it's to allow implicit and explicit use of arguments passed to alias. Git does the following to the alias string[1]:

  argv_array_pushf(out, "%s \"$@\"", argv[0]);
So, you can have aliases like `!grep foobar` to automatically accept arguments or aliases like yours that use arguments explicitly.

I've done aliases like `!bash -c 'foo $1' sh` before, but on seeing yours, I see that it was unnecessary to re-wrap with bash.

[1] https://github.com/git/git/blob/e31aba42fb12bdeb0f850829e008...

Huh I had no idea $1/$2/etc worked as-is in an alias. The advice I learned years ago for dealing with any alias that needs to do something custom with parameters is to write it like

  git config alias.foo '!f() { actual command goes here }; f'
as that will pass all the args to the shell function. But if git is already setting it up so the args work then suffixing the alias with ";:" seems simpler.
> The advice I learned years ago

Being able to use $1/$2/etc directly might be a relatively new development.

EDIT: Or maybe not. This might have been doable since 2010:

https://github.com/git/git/commit/8dba1e634af1d973a47fca616a...

2010 is still “new development” to me
Interesting! Thanks for digging up the code.