At the moment of writing this I’m in the final month of my internship. I am slowly realising how much I have learned in the past few months. But of all the things I have learned, a better understanding and usage of git is one of the thing that had the biggest impact. Whenever I pushed my changes before this internship I would do something like this:
git add . git commit -a -m “added a few features” git push
And that’s it. I would usually do this at the end of the day or whenever I didn’t want to lose progress. However in this company I picked up the habit of committing in a standardised structure called conventional commits.
Instead of ‘just’ writing your message you follow a template that looks like this:
<type>[optional scope]: <description> [optional body] [optional footer]
Every commit has a type that falls into a predefined category, at this company the specific categories are:
feat: a feature that is visible for end users.
fix: a bugfix that is visible for end users.
chore: a change that doesn't impact end users (e.g. chances to CI pipeline)
docs: a change in the README or documentation
refactor: a change in production code focused on readability, style and/or performance.
The scope specifies what you have changed, preferably in a single word.
The description is a one liner that specifies what the change is. You can use the body in case there is more information that should be in the commit message. Finally, there is a footer where you tag relevant issues or pull requests.
An example of a 'conventional commit':
git commit -m "feat(ratings): added the ability to add star ratings to posts. This has been a feature requested by different users. Changes in the database structure where necessary to make this happen. closes #105"
Using this commit structure has impact on how I use version control on a daily basis and on the 'quality' of my commit messages.
I think the most obvious change is that my commits where a lot more descriptive than before. By providing a type and scope it is often a lot more obvious where changes can be found before even looking at the files that are part of the commit. This also allows the description to focus on what changed since other details are known already. Even though the body and the footer are optional they are extremely useful for the future. For instance a body that describes how a certain bug was fixed and to which issue it referred can be very helpful when it turns out that the fix unintentionally caused a change in behavior of other features later on.
When using conventional commits I can't just collect all the changes I have made in a single commit. I have to take my time and think about what I have done in the first place. Based on that I start commit my work. For example, I still edit the docs straight away when I add an important feature or change the CI pipeline. Instead of committing everything in one go I stage certain files and write the appropriate commit message. This feels like a lot of work in the beginning but again when things go wrong or not as expected it is a lot easier find out when the change happened from a version control perspective.
Besides of 'proper' staging there are a lot more git features that I use. To be fair this is also because of other aspects of the git workflow (separation of production and development code in different branches). Rewriting a commit message or deleting my last local commit are some things I didn't do before.
There are more benefits of using this commit structure. One of many is that clear changelogs can be generated by tools and the use of certain keywords triggers some cool features in repository hosting solutions like Github and Bitbucket. The best way to get to know git is by using it. I have to admit that I did mess up here and there when trying out new things. I really recommend the git flight rules repository in case something goes wrong or you’re not entirely sure of how to do something.
Hopefully you’re willing to try out conventional commits yourself.
~ Happy coding :)