Git is sometimes rough around the edges, but fortunately it’s not too difficult to customize and make more user-friendly. The other day I spent some time experimenting with
git log and crafting a new
git smartlog alias.
As much as Greg Heo would like you to believe that I miss using Mercurial, I don’t. 😉 I used
hg for two years while working at Instagram/Facebook and was happy to return to
git as my primary source control management tool. I prefer Git’s model and workflow, but that’s a discussion for another post. Anyway, there is one thing I do miss about
hg — the smartlog extension. You can find this an other Mercurial extensions by Facebook here.
hg smartlogdisplays the graph of commits that are relevant to you, and highlights your current commit in purple.
I wanted this (or something similar) in Git. The closest thing out-of-the-box is
git log, but it’s rather unusable on its own. By default, it lists all commits with the full commit message, along with metadata like date and author. If you want the full history, this works. But rarely does one want this level of verbosity when needing to quickly check recent history or when trying find a specific commit. Give it a try. Run
git log in one of your repos.
Creating an alias
Creating Git aliases (or shortcuts) is easy. For example,
git config --global alias.co checkout sets
co as an alias for
checkout. After setting this, running
git co is the same as the more verbose
git checkout. Note that even with an alias set, both commands will still work.
As you can read in the docs for git-log, there are a ton of options to pass to
log, including an overwhelming amount of “pretty format” options. There’s a more digestible, high-level overview in section 2.3 of the Git book. After experimenting with these various options, here’s what I came up with:
$ git log --graph --pretty=format:'commit: %C(bold red)%h%Creset %C(red)<%H>%Creset %C(bold magenta)%d %Creset%ndate: %C(bold yellow)%cd %Creset%C(yellow)%cr%Creset%nauthor: %C(bold blue)%an%Creset %C(blue)<%ae>%Creset%n%C(cyan)%s%n%Creset'
Obviously, it is impossible to type this every time you want to run
log. So you can set an alias called “smartlog”. You can also find a gist here.
$ git config --global alias.smartlog "log --graph --pretty=format:'commit: %C(bold red)%h%Creset %C(red)<%H>%Creset %C(bold magenta)%d %Creset%ndate: %C(bold yellow)%cd %Creset%C(yellow)%cr%Creset%nauthor: %C(bold blue)%an%Creset %C(blue)<%ae>%Creset%n%C(cyan)%s%n%Creset'"
Here’s a comparison (using IGListKit) between the default
git log (left) and this new
git smartlog (right):
The default log displays the commit hash, author, date, and full commit message. The result is barely seeing just two commits. By contrast,
smartlog displays the 10 most recent commits. Let’s breakdown what’s happening how it corresponds to the options passed to
--pretty=format:. The first line contains the abbreviated commit hash (
%h) in bold, followed by the full commit hash (
%H). If available, ref names (e.g. branches, tags, etc.) (
%d) come after the commit. The second line displays the RFC2822 style date (
%cd) followed by a relative date (e.g. “2 days ago”) (
%cr). Next is the author name (
%an) and email (
%ae). Finally, there’s the commit subject (
%s). Interspersed in
--pretty=format: are color settings, for example
%C(red) sets the color to red and
%Creset resets to the default terminal color. And
%n inserts a newline.
You’ve probably noticed that this doesn’t exactly match the behavior of
hg smartlog, which shows only your commits. You can fix that by specifying an author,
git smartlog --author='Jesse Squires'. You can specify anyone on your team, which could also be useful. That command is rather long, so you can set another alias.
$ git config --global alias.me '!git smartlog --author=Jesse Squires' # usage: git me
Notice that you can reference your previous alias (
smartlog) within this one. You can use the same technique to abbreviate
sl. Yes, you can set aliases for your aliases.
$ git config --global alias.sl '!git smartlog' # usage: git sl
Other useful aliases for Git
Here are a few more aliases that I find useful. Some are simply “shortcuts” for existing commands (like
status) while others provide more a user-friendly interface for somewhat obscure commands (like
alias.co=checkout alias.br=branch alias.cm=commit alias.st=status alias.unstage=reset HEAD -- alias.uncommit=reset --soft HEAD^ alias.purge=clean -fd alias.dif=diff alias.pick=cherry-pick
Git aliases are pretty powerful and super useful to increase your productivity. Not to mention, they help smooth out Git’s rough edges.