The Art of Writing Git Commits for Extreme Programmers (XP)
Why do good commits matter? I am sure most of you in the Software Industry must be familiar with the concept of “stories” in Agile methodology. Every small piece of work is a story. Now break that story down and you have tasks to be done or alternatively, what some product managers call as acceptance criteria. Go one step further and break down each of the tasks and you’ll reach the smallest possible logical unit- a commit. Yep, you got that one right! If your carefully notice, you can actually break down your stories into commits right from the point you start anchoring them. A commit in its most fundamental definition is used to save changes to a repository. How you save those changes matters to everybody — you, your colleagues, your team lead and your manager. Each commit is like the smallest piece of your story. Your repository should be maintained in such a manner that anyone going through it should be able to understand your story and that’s why the smallest unit of delivery as a coder is of utmost importance!
How is a commit different in an Extreme Programming Environment?
Extreme Programming is a methodology of Agile, it’s commonly abbreviated as XP. Going by its Wikipedia definition- it is a software development methodology which is intended to improve software quality and responsiveness to changing customer requirements. Since the focus is on continuous response to customer needs, everything is done to an extreme. Code reviews do not become just important but the breath of the the process. To do code reviews, organizations go to “extreme” levels to enable continuous review of code via pair programming. This is exactly where commits get different. Instead of solo, we have duet commits. This fact, however, doesn’t fundamentally change anything about a good commit. It only adds additional steps of using tools like git duet to commit instead of a simple commit and having a thorough protocol with your pair on when or how to commit.
What makes a good commit?
Although most of us look for an answer to this question, the question itself is a little flawed. It depends on what you are looking for. Are you looking for what message to write? Are you focused on the format of a commit or are you asking when to commit? The ideal answer is — all of it. It doesn’t matter if the format is perfect or if you’ve used imperative language to write the commit message, unless you haven’t gotten the right balance and flavors of all three factors, your commit probably has a lot of scope for improvement. I am briefly going to talk about each of these factors in this post.
When to commit?
This is probably the most important part of this post. It’s a good practice to commit when you think one logical piece of work is done. How do we spot that? I was taught this by one of my seniors and I think there is no better way to do this than what she suggested — Imagine you have been asked to get into production and your commit is the last one commit that has been picked up. Basically, anything after that commit will not go into production. Can you guys still get into production? If your answer is yes than kudos to you because you are doing it right! If no, then think of what next logical step would help you get there? That, probably is one commit. Basically the idea is anyone should be able to slice through your repository and be able to send it into production. This is especially true of a Continuous Integration and Continuous Delivery environment because each of your commits are going into production.
This also brings me to my next point — each commit should be free of compile time errors. Commits with syntax or compile time errors are a big no no! So are commits without tests. Code without tests is , umm, well, useless. You’ll agree with me on this one one day and see for yourself. It’s understood implicitly that whatever code is going is should have tests as part of it. To put it together- commit should be one logical entity, should get compiled without errors and should contain tests associated with it, if any.
What to write in a commit message?
A commit message should be balanced. It should not give too much details like the method names but it should also not be devoid of the kind of classes you touched up on. Commit writing is like an art which gets better with time. Start off by focusing on the title — it should very briefly describe what you’re trying to do like “Refactor xyz controller” or “Integrate models with controllers” etc. The body should describe which controllers and which models are being modified. Maybe some points about anything added — like a file with string constants etc. Ideally a commit should be as loosely coupled as possible.
The body can contain as many more details. The body is primarily for the next set of people working on it. It’s for them to understand what all went into the commit. Making it too long would not help. Being concise and to the point would. This is also a place for you to experiment. I sometimes even leave helpful links there. Review comment numbers, bug numbers or story links should also go here.
Format of commits
Many blog posts suggest that a commit should be written in imperative like a command in linux — “ Fix bugs” not “Fixed bugs” or “Fixing bugs”. To be frank, I can’t agree more with any of them. Nobody can raise a question if you do otherwise. This is recommended for two reasons- it’s very tech savvy — like giving a command and also because Git recommends it. If you carefully notice, Git default commit messages are always like — “Merge branch so and so”. Git never says — “Merged” or “Merging”. This point is highly individualistic though. Not to mention imperative will take lesser space (just trying to sway you towards that).
The first line of the commit message should be short and precise. It’s also highly recommended to wrap your text in around 50 chars.It’s like the title message for all that you have done. This is also what’s displayed as the heading of git log, commits etc. Many people recommend it to be in caps, I am not a big fan of that though. Mainly because it makes readability a challenge in the git repository.
All of the recommendations above are solely based on my learning and experience. They are all just suggestions, let’s leave them at that. At the end of the day, a good commit comes down to what you are comfortable committing with your partner (pun intended) and how often you choose to commit, of course with the limitation of how comfortable your team is with the approach and strategy. I would like to end my post with this one liner “mantra” that I have come to follow after being in XP for a year:
“Commit frequently, push once.”