If you and your team are in the habit of writing good commit messages, it can save everyone a tremendous amount of time and effort. Other developers can very quickly see what you've done. It'll also save tons of time tracking down commits from the past when you need to find them. A good commit message serves exactly two purposes: it gives other developers an explanation of the commit, and it gives some documentation for future searching.
Everyone thinks they write great messages. Most of the time you probably do. But everyone, including you, phones it in from time to time. It's true, admit it. I know you think you write awesome commits but if we looked at your last 100, how many would we truly classify as awesome? Just for fun, try it. I just did. It wasn't pretty.
This isn't really about the message, per se, but it's too important to not mention. A commit should be one (and just one) logical unit. It should be something that someone might want to patch or revert in its entirety, and never piecewise. If it could be useful in pieces, make separate commits. This will result in short, clear, and concise commit messages. Non-atomic commits make for awful run-on commit messages.
A run-on commit:
Fixed a few bugs in the interface. Added an ID field. Removed a couple unnecessary functions. Refactored the context check.
The worst message of all:
Fixed some bugs.
Hey wow, thanks for that.
Usually, this commit follows some previous larger commit that had a bunch of bugs. If so, say so! The lack of search-friendliness in the commit log can come back to haunt you. Be more descriptive. When you are skimming a commit log, or searching for a particular commit, these catch-all messages will be basically useless.
At the very least, name the important subsection/module of the code. "Fixed bad allocations in image processing routines" goes a long a way.
Added super-widget 2.0
Very rough draft of super-widget 2.0. Compiles but is completely untested.
Tested + working super-widget 2.0... but the XYZ function() should be alot smarter to re-use previous computation
While your commit should never break anyone else's build, it's generally acceptable to commit things that aren't "patched in" and aren't necessarily fully working. Just state the important caveats in the commit. This is especially true if you have major line items to do. The third example above states missing functionality for others to see (and possibly implement), and it provides fantastic information when looking at the log for a particular file or module.