I hope this hack is helpful to someone so posting it here. It's based on the answer to this question.
I could have created my own git commands ~/bin/git-<custom command>
but preferred to change my existing git aliases as I backup my .gitconfig
. git commands have the advantage of executing in the current directory when <path>
is mentioned (no need for cd ${GIT_PREFIX:-.}
mentioned below).
I pulled out the replace options logic into a helper fn options
. It's then used for aliases l
(log
), d
(diff
), dt
(difftool
), etc. I intentionally kept that fn in gitconfig
rather than a shell script so everything is in one place. It's easy to add new options to that fn too.
cd ${GIT_PREFIX:-.}
is required to honor <path>
for git aliases that execute as shell commands (see this). This is important for git log
.
Note that shell commands will be executed from the top-level directory
of a repository, which may not necessarily be the current directory.
I already had aliases for log
, diff
, difftool
. It is not possible to have a git alias or custom git command to override a built-in git command and did not want to create one for show
so I left out git show
.
Before:
[alias]
l = !"cd ${GIT_PREFIX:-.} && git lg2"
d = diff
dt = difftool
lg2 = # alias for log
After:
[alias]
l = "!f() { cd ${GIT_PREFIX:-.} && git lg2 $(git options "$@"); }; f"
d = "!f() { cd ${GIT_PREFIX:-.} && git diff $(git options "$@"); }; f"
dt = "!f() { cd ${GIT_PREFIX:-.} && git difftool $(git options "$@"); }; f"
lg2 = # alias for log
#workaround: helper fn to alias options
options = "!f() { \
echo "$@" \
| sed 's/\\s/\\n/g' \
| sed 's/^--ns$/--name-status/' \
| sed 's/^--no$/--name-only/' \
| xargs; \
}; f"
So now I can do:
git l --ns
git d head~ --ns
git dt head~ --ns
# with paths:
git l --ns -- <path>
git d head~ --ns -- <path>
git dt head~ --ns -- <path>