Commit Early, Commit Often
Any developer can commit code — but knowing when to commit is often up for debate.
Most developers will admit that making a commit for every changed character, or keystroke is not best practice. After all, having too many commits can cause confusion, and clutter your commit history.
On the other hand, committing large chunks of code could lead to unfocused and incoherent commits. Somewhere in there is a happy medium, but how do you find that?
At Wildbit, we promote best practices by encouraging developers to commit early, and often. This article will focus on the benefits of doing just that. To begin, let’s focus on two attributes to keep in mind when making commits.
Commit Messages
We often talk about the importance of writing meaningful commit messages. These messages define the commit itself, and should be about one specific set of changes. And those set of changes should support that message.
In this light, addressing two separate bug fixes in a single commit, even if they are related would not be wise. Why? Good commit messages are often overlooked until you need to go back and find a specific change. But how do you locate that change if you habitually combine multiple changes into a single commit? It’s not impossible, but it’s not preferable, either.
With that said, here’s a question to ask yourself if you’re wondering what code to include in your commit.
“When I write my commit message, will it be about a single subject? Or will I be forcing other random and unrelated details from a separate issue?”
If you foresee yourself having difficulties constructing a clear, and defined message, it may be better to create two or three separate commits to flesh out your work.
What’s another way to test the quality of your commits?
Rolling Back
Let’s consider another scenario. Think in terms of rolling back to a previous commit. If you want to know if you’ve included too many changes in your commit, ask yourself:
“If I rollback to the previous revision, how much work would I lose?”
Let’s go back to our example earlier, but this time we’ll view this with a different lens.
You’ve fixed two separate, but related issues. You add these changes to a single commit, but then you realized you introduced bad code when fixing one of the bugs. Now you need to rollback to a previous state. But how do you do that without removing the useful code you prefer to keep?
This is where things can become tricky, and in most cases you find yourself wishing you had segregated each bug fix into their own commits. When you have the habit of committing early, and often it’s easier to see the journey of your feature.
Don’t take my word for it. Let’s test this out. Here are two git log code snippets of the same repository. Which snippet tells you more about the feature that’s being added?
Example 1
commit b0e77532b5a8cf236d95f1b3324aabc194568c60
Author: Ashley
Date: Tue Feb 29 23:12:05 2011 -0600
added contact us box to homepage and about us page
Example 2
commit b0e77532b5a8cf236d95f1b3324aabc194568c60
Author: Ashley
Date: Tue Feb 29 23:32:03 2011 -0600
added text fields on home page
commit b0e77532b5a8cf236d95f1b3324aabc194568c92
Author: Ashley
Date: Wed Feb 30 00:52:09 2011 -0600
added text fields on about us page
commit b0e77532b5a8cf236d95ashdad44aabc194568c12
Author: Ashley
Date: Wed Feb 30 01:15:32 2011 -0600
added buttons, and edit and delete options
The first code snippet describes the commit effectively. But that’s all it does. All the code has been consolidated into one single commit. If you’re looking for a specific piece of code, you’d have to sift through a lot of changes to find it. That’s not the ideal experience if you run into issues down the road.
The second code snippet shows the journey of this feature and how it has evolved over time. Now, you can revert to specific points of your development, without the fear of losing all of your changes. With this approach, it’s easier to show your colleagues all the changes that led to the end result.
Imagine walking up a flight of stairs that has missing steps. You may be able to get to the top, but if the gaps are too large, then it can be difficult.
Likewise, making small atomic, and self sustaining commits help you to think through the implementation process and write better code. If there are too many gaps in your commit history, it can generate a lot of confusion making it difficult to journey through your project.
Benefits
To summarize, what are the benefits of committing early, and often?
It’s easier to share your code. If you’re on a distributed team, its best to share your code as much as possible. Your teammates can integrate changes, and avoid merge conflicts worry free.
Context. When you commit early, and often you give your team and yourself a great deal of context. How so? It’s easier to track where a change was introduced because you have a detailed commit history. Introducing too many changes in a single commit, it makes it harder to locate problems when they come up.
Scope. Committing early and often will help you to see the journey of your project, making it easier to rollback to a specific revision if needed
Better commit messages. Better code. By committing often your messages will be focused, and meaningful because it relates to a specific set of changes, and not a series of unrelated modifications.
Summary
Remember, the purpose of the change is more important than the size of the change. Some developers feel that if you’ve only changed 1 or 2 lines of code, then you’re cheating yourself by committing a small amount of work. But that’s not entirely true. A small change like fixing a typo is worthy of having its own commit.
Don’t feel rushed to commit code because you’re wrapping up your work day. Remember, git stash is your friend that stores your changes until you’re ready to commit them. Save yourself time and improve the quality of your code by committing early, and often.
Click here to download our “Commit Early, Commit Often” poster.