Like Andrew, I often break a large commit into a series of smaller commits by interactively selecting chunks that form logical groups. But usually I'll commit often enough that there's no need to break it up.
I also takes notes that will go into the commit if I know some part of a change will need explanation (e.g., why the new code is preferable to the old). But most of the time looking over the chunks while I commit is enough to recall the reason I made the change.
I find it helps me and my teammates to commit frequently because that's a hell of a lot easier to review than one massive commit with a message that provides no useful information.
More frequent commits also means it's easier to fix the build if you break it.