threads / discuss / 33377

Two potential bugs in aliases that expand to shell commands

Subject: Two potential bugs in aliases that expand to shell commands

## tl;dr

2 messages between Apr 4, 2013 and Apr 4, 2013.

replies: 1people: 2as markdown or json

Han· Apr 4, 2013, 02:05 UTC · lore
These might just be documentation bugs.

Aliases that expand to shell commands are only documented fairly superficially, but `git help config` does say: "If the alias expansion is prefixed with an exclamation point, it will be treated as a shell command."

It also says, nearer the beginning: "String values may be entirely or partially enclosed in double quotes. You need to enclose variable values in double quotes if you want to preserve leading or trailing whitespace, or if the variable value contains comment characters (i.e. it contains # or ;)."

There appears to be another case string values need to be enclosed in quotes, which is a shell command where you want to preserve quote characters (not leading or trailing); a minimal example is

  shortcut = !cd "" && pwd
will act like you ran, in bash,
$ cd  && pwd
and print your homedir path, whereas
  shortcut = !"cd \"\" && pwd"
will act like you ran, in bash,
$ cd "" && pwd

and stay in the top-level directory of the repo (which is where aliases that expand to shell commands are run from).

This is problematic precisely because aliases that expand to shell commands are run from the top-level directory of the repo: if you had an alias that worked great at the top-level directory, like

  shortcut = !do_something

but it was doing the wrong thing in subdirectories, my first instinct, at least, upon reading "Note that shell commands will be executed from the top-level directory of a repository, which may not necessarily be the current directory. GIT_PREFIX is set as returned by running git rev-parse --show-prefix from the original current directory.", is to do

  shortcut = !cd "$GIT_PREFIX" && do_something

which will now do the right thing in subdirectories, but at the top-level directory of the repo, $GIT_PREFIX is undefined/the empty string, and it cds to your homedir.

The other bug I'm much more confused by. If you have an alias like
  shortcut = !"echo -n lol; echo wut"
it will, in fact, print

-n lol wut

which is, uh, not what bash prints. Is git special-casing echo?

(I discovered these while adding something semi-jokingly to my .gitconfig: https://github.com/laughinghan/dotfiles/commit/34f5528825b287ff40acfe57808b32931a87261c )

Han
Jeff King· Apr 4, 2013, 06:40 UTC · re: Han · lore

Re: Two potential bugs in aliases that expand to shell commands

On Wed, Apr 03, 2013 at 07:05:33PM -0700, Han wrote:
Show 5 quoted lines
> There appears to be another case string values need to be enclosed in
> quotes, which is a shell command where you want to preserve quote
> characters (not leading or trailing); a minimal example is
> 
>   shortcut = !cd "" && pwd

Yes. You must escape any double-quotes that are not the beginning or end of a quoted string.

>   shortcut = !"cd \"\" && pwd"
This is fine. Technically so is:
  shortcut = !cd \"\" && pwd

but I think it is more readable to put such shell snippets inside a double-quoted string, to make it more clear what is going on.

Documentation patches welcome.
Show 10 quoted lines
> The other bug I'm much more confused by. If you have an alias like
> 
>   shortcut = !"echo -n lol; echo wut"
> 
> it will, in fact, print
> 
> -n lol
> wut
> 
> which is, uh, not what bash prints. Is git special-casing echo?

No, git does not special-case echo. But it runs shell commands with /bin/sh, which may or may not be bash on your system (and "-n" is not necessarily portable to other POSIX shells).

If you really want to use bash, do:
  shortcut = "!bash -c 'echo -n lol; echo wut'"
or just use printf, which is a portable way to spell "echo -n".
-Peff

← back to recent threads