Note: this is an extract from Heyday's internal docs, written by me. Published as a Gist to share the love.
We like sensible commit messages. There're a lot of good articles about writing great, useful commit messages, but here's the gist of what we like:
- The single most important thing is: commit messages should explain why you are making the change.
- Think, "what would future me want to know about this change?"
- Avoid committing multiple sets of ideas/changes in the same commit: split them up.
- Don't assume the reader understands what the original problem was.
- Don't assume the code is self-evident/self-documenting
The main reason to fill your commit history with useful information is so that you, other developers, and future you can understand the context and reasoning behind changes to code, without talking to the original developer (who might be long gone, or has at least forgotten the reason their code is the way it is). Git provides a lot of tools for working with the history, which are useful once you get to know them - you can make use of all these awesome commit messages everyone has been writing. Also consider:
The body of commit messages can document all of the things that probably don't belong in code comments.
Relevant quotes from emails, error messages, ticket numbers, links to discussions about issues, relevant articles, specific reasons for choosing a solution, thoughts about alternative solutions.
Is this the best solution? Have I missed something? If it's a hack, then why is it ok? Can it be avoided? Can the problem be solved in a better way? If you've done something hacky and can't justify it, should you really be doing that?
Header line: explain the commit in one line
Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc etc.
Make sure you explain your solution and why you're doing what you're
doing, as opposed to describing what you're doing. Reviewers and your
future self can read the patch, but might not understand why a
particular solution was implemented.
Fixes BUG-123
That header line really should be meaningful, and really should be just one line. The header line should summarise the change in one readable line of text, independently of the longer explanation.
If you have time and really want to be awesome, here's some more information about what makes good (and bad) commit messages:
- Writing Reviewable Code - Phabricator team
- Git Commit Good Practice - Open Stack
Git has a lot of powerful tools for digging through the history of projects. While these are not all everyday tools, being aware of and including them in your workflow can be very useful when you do need to dig through the history of a project.
Most editors have the capability to quickly access information from a project's history, either by a built-in function or through a plugin. If you're using Sublime Text, sublime-text-git is a good solution that allows quickly blaming lines and viewing older versions of a file through the command pallete. In PHPStorm you can right-click on the margin of an editor and select "Annotate". SourceTree also exposes a few simple history searching features, which can be a good place to start.
A bunch of useful (but not particularly well advertised) tools that are bundled with Git. These are all started on the command line inside a repository.
If you just need basic search of code and commit messages in the history, SourceTree's search view can do this. You can alternatively use git log
on the command line with one or two flags to achieve the same thing.
{F697 size=full}
Gitk is a GUI that can utilise most of the filters available in git log
. It's looks a bit like SourceTree, but it's only for working with history (to stage, commit, merge, etc the sibling program is git gui
). Most of the functions listed below can be achieved with or started from gitk.
Basic usage:
- A simple code, path, and commit message matching filter is along the middle of the window
- More filter settings are under the "View" > "New view" menu
- The default font size is pretty small. You can bump this up in the application's preferences
{F685 size=full}
Git's blame GUI is fundamentally the same as git blame
or your editors annotate/blame functionality, however it's smarter than "who last edited that line" - allowing drilling back through the history inside a single file, as well as identifying where code actually came from, rather than who put it where it is now. This makes it a trivial task to find out who originally wrote lines that have since been copy-pasted around, re-indented, and moved between files.
{F689 size=full}
This makes it possible to track when a code snippet was added to a file, moved or copied between files, and eventually deleted or replaced.
git log --grep 'case-sensitive string/regex'
- Find commits where the log message matches a string/pattern
Another reason to add detail to commit messages: you can search them later in addition to the searching for code changes.
Bisect is one of those tools you might use once in an aeon, but it's a life-saver when you do. Particularly useful when working with code that you're not familiar with, or a bug you can't pin down, git bisect
asks for a known bad commit (where your bug is), and a known good commit (somewhere in the past that works correctly), then steps you through commits in the most efficient sequence to find the exact commit that introduced the problem.
See Git Tools - Debugging with Git for more information on this binary search function.