Tip of the day: Embed Git commands directly into the shell
June 21, 2010
Git has an aliasing feature that allows you to define aliases and shortcuts for Git commands. For example, the command
git config --global alias.st status
will setup “git st” as a shorthand for “git status”. To delete the alias, use
git config --unset --global alias.st
But that’s not the point of this post. Recently, I have become tired of typing the four letters “git ” at the beginning of each and every Git command. At least for often-used commands which I have abbreviated already with Git aliases, I want to be able to omit the “git “. Of course there’s a shell script to solve my problem.
while read git_line; do
if echo $git_line | grep '^\[.*\]$' &>/dev/null; then
git_category=$git_line
else
echo $git_category $git_line
fi
done < $HOME/.gitconfig | grep '^\[alias\]' | cut -d' ' -f2- | sed 's/ = / /' | while read git_alias git_command; do
alias $git_alias="git $git_alias"
done
unset git_line git_category git_alias git_command
Put this into your .bashrc (or equivalent). Please note that the above script was only tested with zsh, but I do not see anything that should not work in bash as well.
Now what does this do? For every global Git alias (like “git st” for “git status”), it defines the alias as a command recognized by the shell, so you need to type only “st” instead of “git status”. Git aliases can also resolve to the same command without entering an infinite loop, so you can define “pull” as an alias for “pull”, and use “pull” as a command on the shell.
June 21, 2010 at 17:46
What about semi-dynamic namespaces? Checking if your current working directory contains a git-repository and only then admitting those aliases. That would minimize the risk of collisions (or make them less likely to affect things).
June 21, 2010 at 19:46
If I knew of a way to dynamically assign aliases per cwd, I would do it, but I don’t. One could possibly hack into `cd` by aliasing it to a user-defined function, and then set and unset aliases, but that’s not worth the effort for me.
June 22, 2010 at 08:23
You can put whatever you want in an alias:
trunk 0 $ alias info=”[[ -d .git ]] && git mailinfo”
trunk 0 $ info # svn checkout, so the test fails -> 1 return status
trunk 1 $ cd gemrb # git clone
gemrb 0 $ info
usage: git mailinfo [-k|-b] [-u | --encoding= | -n] [--scissors | --no-scissors] msg patch info
June 22, 2010 at 12:04
You can use zsh’s pre-exec hooks to set or unset an alias, based on the cwd.
Basically, those pre-exec hooks allow you to do something whenever a command is entered on. It’ll first run whatever is in the pre-exec hook, then the command itself, then a post-exec hook.
Pretty neat mechanism.