Shell Tricks: One Git Alias to Rule Them All

[Tweet : ADN : nvALT]

Continuing the Shell Tricks series, here’s a handy Git trick. I’ll be moving away from the Git tips soon, so don’t lose heart if you love the command line but aren’t a big Git fan.

When I discover cool new Git commands, I tend to alias them in my global .gitconfig file to help me remember how to use them. You can see what any alias is by running with git help aliasname, so when I use them I like to check that and start memorizing the actual commands. Sometimes, though, I’ll know I figured out a trick but can’t remember what it’s aliased as. Then I have to list all of my aliases, grep for the one containing the base command I’m looking for, and then work to memorize that.

Here’s a trick for doing all of that at once. First, we use the git config command to list all of our aliases, which is pretty simple:

$ git config --global --get-regexp alias
alias.type cat-file -t
alias.dump cat-file -p
alias.r remote -v
alias.unstage reset HEAD
alias.uncommit reset --soft HEAD^
...

That just lists all the configured options that match the term “alias”.

We can clean up that output with a little bit of awk. We want to clean out the alias. at the beginning of each line, and then separate the first field from the remainder for eventual styling.

git config --global --get-regexp alias \
| awk -v nr=2 '{sub(/^alias\./,"")}; \
{printf "%s", $1}; \
{sep=FS}; \
{for (x=nr; x<=NF; x++) \
{printf "%s%s", sep, $x; }; \
print "" }'

There’s probably a simpler awk command to do the separation part, but I kept running into problems using substr() in the awk command so defaulted to a for loop. You can also simplify it using a cut command instead, but it doesn’t work with the next part.

You can combine this with grep and stop here, if you want:

git config --global --get-regexp alias | grep -i "$@"

But I want to style the output with some colors and alignment…

git config --global --get-regexp alias \
| awk -v nr=2 '{sub(/^alias\./,"")}; \
{ printf "\033[31m%_10s\033[1;37m", $1}; \
{sep=FS}; \
{for (x=nr; x<=NF; x++) \
{ printf "%s%s", sep, $x; }; \
print "\033[0;39m"}'

That will output a list of aliases with the first column right justified and colored in red, and the alias definition in white and left justified:

      type cat-file -t
      dump cat-file -p
         r remote -v
   unstage reset HEAD
  uncommit reset --soft HEAD^
   filelog log -u

One more thing to do: make this a git alias with the ability to search for a substring in the alias!

In ~/.gitconfig, add a line under the [alias] section like this:

finda = "!grepalias() { git config --global --get-regexp alias | grep -i \"$1\" | awk -v nr=2 '{sub(/^alias\\./,\"\")};{printf \"\\033[31m%_10s\\033[1;37m\", $1};{sep=FS};{for (x=nr; x<=NF; x++) {printf \"%s%s\", sep, $x; }; print \"\\033[0;39m\"}'; }; grepalias"

Now, when I run git finda log, it outputs:

…and I never forget a nifty alias again.

Ryan Irelan has produced a series of shell trick videos based on BrettTerpstra.com posts. Readers can get 10% off using the coupon code TERPSTRA.