Maintainable software projects usually take the issue tracker seriously. More often, it is used not only to monitor bugs and defects, but also to serve as a task tracker. This practice permits the cross-reference between the commit message and the associated entry in the issue tracker, thereby allowing anyone to find the in-depth reasoning or discussion behind a particular commit.
If a project is hosted on GitHub, a cross-reference between the issue tracker and the commit log is handled automatically. As an example, the relevant commit log of PhantomJS revision 3edcabef is:
Fix compilation with MSVC 2010
Issue #10158: https://github.com/ariya/phantomjs/issues/10158
Because of the reference
Issue #10158, GitHub will link this commit with the said issue. If we go and take a look at issue #10158, the above commit will be mentioned, interleaved with other comments. Very handy!
Since this cross-reference is quite useful, some projects mandate it as part of its contribution guide (house rules). Other extra advantages:
- Commit log is “frozen”, issue entry can always be updated
- Issues can be categorized/tagged/organized easily
For various reasons, many software projects are not hosted on GitHub. How do those projects, particularly the large ones, implement the cross-reference?
First, let us take a look at Mozilla project. In its Mercurial repository, Mozilla contributors typically use a short, one-line commit message. As an example, have a look at revision d71234d65e90:
Bug 678037 – Add (disabled) ability to parse script bytecode lazily, r=luke
Also, we notice that there are some links back from the bug entry to the related revisions, pointing to the said check-ins. This is quite important as we can trace the changesets in the source repository which are part of the development of this bug. Often, changes need to be tweaked, staged, reverted, and rewritten. By keeping such a cross-reference, it is easy to follow the whole process.
Another large software project, WebKit, also has a similar contribution workflow, particularly with its tiered committer-reviewer level. WebKit commit message is however more verbose, it is more than just a very brief one-liner. If we pick revision 147858, it looks like:
Unify the many and varied stack trace mechanisms, and make the result sane.
Reviewed by Filip Pizlo.
Makes JSC::StackFrame record the bytecode offset and other necessary data
rather than requiring us to perform eager evaluation of the line number, etc.
Note the same pattern of bug link, reviewer, and the changeset explanation (both in the short form and the more verbose version). Again, if we visit bug #114072, there is a link pointing back to that particular revision.
Last but not least, how does Chromium handle this? It is actually pretty similar (surprise), its contribution guide describes the details. Here is an example check-in, revision 191268:
TextureLayer: clear texture id when clearing client.
This is to avoid having the impl side accessing a texture that’s been deleted.
Review URL: https://chromiumcodereview.appspot.com/13126002
The commit message lists the bug id and the review URL. The latter, issue 13126002, is where the discussions and code reviews take place (the web interface works on an instance of Rietveld). The actual problem is still kept in the issue tracker, i.e. bug #224308 in this case. This forms an interesting connected triangle, whether you start from the bug entry, the code review, or the commit message, you can easily find the other two.
It seems tedious to open or reserve a bug every time you want to work on something. However, considering the benefits, it will be time well spent. Many projects usually give the contributors a set of helper scripts which can conveniently create the bug entry and also handle the rest of the workflow with the purpose of streamlining the entire process. As an example, Chromium uses depot_tools which (among others) permits the interaction with the code review tool just from the command-line.
Do you also practice such a cross-reference in your project? Share your story!