Mar 31, 2014
Each commit should correspond to a single logical change: changing coding style, fixing a bug, doing a refactoring, adding a feature, etc. You should not put several logical changes in one commit like changing coding style and fixing a bug simultaneously.
You should be able to describe in a commit message what you’ve changed without using words like “and”. For example, if you’re urged to write a commit message like “Fix and rename the user creating method”, you should split it into two commits “Fix the user creating method” and “Rename the user creating method”.
A good way to decide if changes should go to a single commit or be split is to ask yourself the following two questions:
If a commit might get reverted, will that revert something else you don’t want to revert?
Say, you find out that a commit was wrong in some way and you want to revert it. If the commit was not atomic, you’ll have to revert other changes too, but that might not be desired.
For example, you fixed a bug and refactored some code. It turned out that the bug fix actually broke something but the refactoring was good and useful. If you shoved both changes in a single commit, you’ll have to revert both changes; if they were in separate commits, you could keep the refactoring and revert the bug fix.
Provided you’re contributing to someone else’s code, is it possible they might want to merge only some of your changes and reject the others?
Even if you’re working on your own project, pretending you’re contributing to someone else’s may be useful.
Say you’ve fixed a bug — really fixed it this time — and refactored some code. The project owner likes the bug fix and wants to merge it but for some reason she doesn’t like your refactoring. Probably you violated some project coding guidelines.
If you did both changes in one commit, it might be problematic to extract only the bug fix related changes to merge them; if they were in separate commits, the project owner could just merge the bug fix and reject the refactoring.
Don’t take it to extreme and keep in mind that each commit should keep the code in a consistent state. That means that a commit should not represent a part of a work in progress that breaks code. For example, if you’re renaming a method, you should also update the code that calls that method and make a single commit with these changes. It’s not okay to make one commit that renames a method and another commit that updates the code calling that method because the code is broken before the second commit gets merged. Even if you do both commits in a row, remember that one of them could get reverted.