Stay Sane with Graphlog

posted by Steve Losh on October 3, 2009

One of the very first Mercurial commands you learn is hg log. It lets you view a log of all the commits in the repository. Here’s a sample of what its output looks like:

$ hg log
changeset:   2:7b393734ccf7
tag:         tip
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:13 2009 -0400
summary:     Do some more work.

changeset:   1:26ac605206b4
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:08 2009 -0400
summary:     Do some work.

changeset:   0:ef4afb3d9699
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:00 2009 -0400
summary:     Initial commit.

$

Not too bad! It works just fine if you’ve just got a straight line of changes with no branches, but once you start branching it can get hard to read. Let’s look at the output after a few more commits:

$ hg log
changeset:   8:b58f37a6f0af
tag:         tip
parent:      3:fee36cf81486
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:48:55 2009 -0400
summary:     Oh god the server is on fire fix it now.

changeset:   7:8f54b4d0d885
parent:      5:ce29b9e5288f
parent:      6:1dff6084cda4
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:48:20 2009 -0400
summary:     Go back to the old wording.

changeset:   6:1dff6084cda4
parent:      4:3c52ba0b77af
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:47:23 2009 -0400
summary:     Actually, the wording was fine.

changeset:   5:ce29b9e5288f
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:46:21 2009 -0400
summary:     Add some content.

changeset:   4:3c52ba0b77af
parent:      2:7b393734ccf7
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:46:04 2009 -0400
summary:     Change some wording around.

changeset:   3:fee36cf81486
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:45:50 2009 -0400
summary:     Fix a horrific bug.

changeset:   2:7b393734ccf7
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:13 2009 -0400
summary:     Do some more work.

changeset:   1:26ac605206b4
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:08 2009 -0400
summary:     Do some work.

changeset:   0:ef4afb3d9699
user:        Steve Losh <steve@stevelosh.com>
date:        Fri Oct 02 23:42:00 2009 -0400
summary:     Initial commit.

$

Now it’s not quite so easy to see exactly what’s going on. There’s at least one merge (because changeset 7 has two parents) so there must be a branch somewhere. Can you spot it easily at a glance, or does trying to figure it out drive you crazy?

To make the log easier to understand, you can enable the graphlog extension by editing your ~/.hgrc file to contain:

[extensions]
graphlog =

Now you can use hg glog to view an ASCII-art graph of the log, like this:

$ hg glog
@  changeset:   8:b58f37a6f0af
|  tag:         tip
|  parent:      3:fee36cf81486
|  user:        Steve Losh <steve@stevelosh.com>
|  date:        Fri Oct 02 23:48:55 2009 -0400
|  summary:     Oh god the server is on fire fix it now.
|
| o    changeset:   7:8f54b4d0d885
| |\   parent:      5:ce29b9e5288f
| | |  parent:      6:1dff6084cda4
| | |  user:        Steve Losh <steve@stevelosh.com>
| | |  date:        Fri Oct 02 23:48:20 2009 -0400
| | |  summary:     Go back to the old wording.
| | |
| | o  changeset:   6:1dff6084cda4
| | |  parent:      4:3c52ba0b77af
| | |  user:        Steve Losh <steve@stevelosh.com>
| | |  date:        Fri Oct 02 23:47:23 2009 -0400
| | |  summary:     Actually, the wording was fine.
| | |
| o |  changeset:   5:ce29b9e5288f
| |/   user:        Steve Losh <steve@stevelosh.com>
| |    date:        Fri Oct 02 23:46:21 2009 -0400
| |    summary:     Add some content.
| |
| o  changeset:   4:3c52ba0b77af
| |  parent:      2:7b393734ccf7
| |  user:        Steve Losh <steve@stevelosh.com>
| |  date:        Fri Oct 02 23:46:04 2009 -0400
| |  summary:     Change some wording around.
| |
o |  changeset:   3:fee36cf81486
|/   user:        Steve Losh <steve@stevelosh.com>
|    date:        Fri Oct 02 23:45:50 2009 -0400
|    summary:     Fix a horrific bug.
|
o  changeset:   2:7b393734ccf7
|  user:        Steve Losh <steve@stevelosh.com>
|  date:        Fri Oct 02 23:42:13 2009 -0400
|  summary:     Do some more work.
|
o  changeset:   1:26ac605206b4
|  user:        Steve Losh <steve@stevelosh.com>
|  date:        Fri Oct 02 23:42:08 2009 -0400
|  summary:     Do some work.
|
o  changeset:   0:ef4afb3d9699
   user:        Steve Losh <steve@stevelosh.com>
   date:        Fri Oct 02 23:42:00 2009 -0400
   summary:     Initial commit.

$

Now it’s much easier to see exactly where things branched.

I personally like to have a bit more compact output from hg glog because I usually don’t need most of the information about each commit. I’ve edited my ~/.hgrc file to contain:

[defaults]
glog = --template 'changeset:   {rev}:{node|short} {tags}\nsummary:     {desc|firstline|fill68|tabindent|tabindent}\n\n'

With that template set as the default, my hg glog output looks like this:

$ hg glog
@  changeset:   8:b58f37a6f0af tip 
|  summary:     Oh god the server is on fire fix it now.
|
| o    changeset:   7:8f54b4d0d885  
| |\   summary:     Go back to the old wording.
| | |
| | o  changeset:   6:1dff6084cda4  
| | |  summary:     Actually, the wording was fine.
| | |
| o |  changeset:   5:ce29b9e5288f  
| |/   summary:     Add some content.
| |
| o  changeset:   4:3c52ba0b77af  
| |  summary:     Change some wording around.
| |
o |  changeset:   3:fee36cf81486  
|/   summary:     Fix a horrific bug.
|
o  changeset:   2:7b393734ccf7  
|  summary:     Do some more work.
|
o  changeset:   1:26ac605206b4  
|  summary:     Do some work.
|
o  changeset:   0:ef4afb3d9699  
   summary:     Initial commit.

$

For me, that’s much easier to read and it gives me all the information I need. If I want to know more about a particular changeset I can use hg log -r REV or hg show REV.

Using hg log works great until you have a few branches, then it gets crazy. Graphlog can save you.