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.
How it works
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.
1. More descriptive commits
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.
2. A change in workflow
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.
3. Using more git features
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 :)
Top comments (21)
Hi Imani, thanks for your post! Didn't know there was a spec about git commits and it's very interesting! It really makes sense since we tend to be "conservative" about explaining commits usually.
In addition you might want to setup a template (basically put the template you explained up there in a template file :D) for your Git commit messages, so that it can help you and the people you collaborate with, with something like:
Another feature I did not know about! This one will be very useful, thanks for sharing ✨
I've used GiT for over a decade and did not know about this. TYVM @rhymes and @Imani.
Great post about conventional commits Imani! We've been doing it for a year now at Peakfijn (a company I work for), and I never want to go back. We've had some discussions within the team about the types we need and eventually, we created our own type-list based on Angular conventions.
Our biggest problem was to get everyone committing valid commits. Along the way, we found some great tools which can really help. Especially when combining this in an automated continuous integration system! Hope it can help anyone :)
Disclaimer; I became one of the maintainers of Commitlint and wrote an Expo plugin for Semantic Release
I'd also add commitizen to that list. It walks you through the steps, at commit, to get the message correct without having to memorise the syntax.
Really great when used in combination with the above tools.
These are some gems! I'll definitely try them out in my upcoming projects :D
Also check out sethrobertson.github.io/GitPostPro.... It discusses how to take a lot of smaller commits (which is a good practice of course) and use git rebase to make a single, well documented commit to push.
I'll definitely check it out, seems like that one thing I'm still missing in my current flow
git -a -m "message"
can be shortened togit -am "message"
btw 😊Neat!
I think active voice would make it even better, eg:
There are also more fun ways using emojis for commit categories. Have a look at these projects:
But the development team should be not too serious in their ways of working if you choose these.
I am guilty of using emoji's in my commit messages when I'm building small homework assignments I had no idea people have created 'specs' for this 😂
Hi Imani, thanks for sharing your experience with us! When I started using git, I was the same way when creating my commit messages.
I did mostly to save progress or bundle all the changes to have one commit. After getting more involved in the dev community and discovering resources. I was able to discover The seven rules of a great Git commit message. This convention has similar rules to your specs. If you really want to enforce these rules, you can create a template as well as git hook so it won't let you commit unless it meets the criteria you set.
"When using conventional commits I can't just collect all the changes I have made in a single commit."
I use to do this. Make a lot of changes in many files and dump them in a single commit. Now I commit small and often. But since the commits are small, I try to use as few words as possible, for the commit message. This results in non-descriptive commit messages.
I have to spend a bit more of my time on writing better, descriptive commit.
Thanks for your post.
Messages are really a pain at times, I really hope this helps 😊
I've fallen into the trap of trying to follow conventional commits only to forget or make a typo which will get pushed. So I made Sailr [1] which is an installable Git hook to help you follow the standard. It's flexible and configurable so you can adapt it to your own implementation.
[1] - github.com/craicoverflow/sailr
Add partial file Commits to your tools if you haven't already.
Partial Commits with Git
Jesse Phillips
I've started pushing to bring this conversational commit to my work.
Nice, I'll definitely try it out :)