Git aliases that run an external command are run from the repository root
Verify this by creating an alias in ~/.gitconfig
like so:
pwd = "!f() { pwd; }; f"
and you’ll find that, no matter where you call git pwd
from, it always prints
the repository root directory.
This is annoying for git diff --relative
aliases where it’s desirable to have
the printed filepaths relative to the current directory.
For example, until five minutes ago I had this alias for printing all files touched in a pull request:
prfiles = "!f() { git diff --relative --name-only origin/master...HEAD; }; f"
but this would print the path from the repository root, meaning you couldn’t pipe the output to a command unless your current directory was the repository root.
The solution is to use the $GIT_PREFIX
environment variable which contains the
directory where the alias was invoked. So my prfiles
alias is now:
prfiles = "!f() { cd ${GIT_PREFIX:-./}; git diff --relative --name-only origin/master...HEAD; }; f"
Note, we define a default value of ./
as $GIT_PREFIX
isn’t set when the
alias is invoked from the repository root.
Now I can run things like:
git prfiles | xargs rg -l "foo" | xargs -o vim
to edit all files from my pull request that contain “foo”.
The $GIT_PREFIX
variable has been available since
v1.7.6).
It’s a little hard to find as it isn’t mentioned in the
current online docs on aliases
but is documented in the man pages (try man -K GIT_PREFIX
).