loading...
Cover image for Enhance your git log with conventional commits

Enhance your git log with conventional commits

maxpou profile image Maxence Poutord Updated on ・3 min read

Git is a very powerful tool installed on most of our machines. As developer, we use it every day. But, unfortunately, at first glance, this tool is not very developer friendly. That's why a lot of people bypass the command line interface (CLI) with a graphical user interface (GUI).

It's like using a framework without knowing the language itself. It can be OK at the beginning but, sooner or later you, you will have problems.

Let's take an example:

$ git log --oneline ./src/components/button/

daccff1f test should pass
3fff19f6 test should pass
5b998d9a add disabled property for button
06faab4d fix lint
186cce90 refactor button
4b99d91a fix spinner component
5b998d9a fix css
263288a5 test should pass
c3fb85af Create Button component

There's might be nothing wrong for you with this log. Let me show you the issues I've found with this log:

  • It's hard to understand the Component's history. We might repeat errors already fixed.
  • There are unnecessary commits which pollute logs and make history hard to read. Also, functionalities like git blame become irrelevant.
  • It seems that a feature was added by a few commits. Which commit should I include if I want to revert this operation?
  • 4b99d9a say something about a different component. Is it an unwanted change? Again, what if we need to revert?
  • ...

I think we shouldn't confound git commit with ctrl + s. A git log should be like reading a story. By reading the log, I should be able to understand in ~10s the whole file history.

What if we had something like this:

$ git log --oneline ./src/components/button/

06faab4d revert: feat: add disabled property
186cce90 feat: add disabled property
5b998d9a test: add scenario for readonly property
263288a5 fix: fix css when hover
c3fb85af feat: add button component

Way cleaner, isn't it?
That something called Conventional Commits.

Conventional commits

Conventional commits is a Git commit convention made by the Angular team. Basically, every pull request should end up with one commit and a standardized commit message.

The message should follow this regex:

/^(revert: )?(feat|fix|docs|style|refactor|perf|test|chore)(\(.+\))?: .{1,50}/

Types of commit:

  • feat: Add a new feature (equivalent to a MINOR in Semantic Versioning).
  • fix: Fix a bug (equivalent to a PATCH in Semantic Versioning).
  • docs: Documentation changes.
  • style: Code style change (semicolon, indentation...).
  • refactor: Refactor code without changing public API.
  • perf: Update code performances.
  • test: Add test to an existing feature.
  • chore: Update something without impacting the user (ex: bump a dependency in package.json).

Project that uses this convention: Angular, Vue.js, Gatsby (almost), Lerna (almost), jest (almost).

Benefits

Project/code understandability

Commits are more descriptives and it's easier to understand the project's history. It became also easier and to contribute.

For example, I never contributed to the Angular's http package. But, reading the repo's git log helps me to better understand this package's history.

Usability

If you have one action per commit, it became easier to revert a change. Same if you have git conflict...

Master your Git skills

Because not all Git-repository manager have a "squash and merge" option, you sometimes have to do this operation by yourself. So, you will learn how to "squash" your commits, how to "fixup" a commit, how to remove a specific commit...
It's always important to know what's going on under the hood!

See also

Originally published on maxpou.fr.

Posted on Mar 11 '19 by:

maxpou profile

Maxence Poutord

@maxpou

πŸŽ’ Digital nomad β€’ πŸ‘¨πŸΌβ€πŸ’» Software engineer β€’ πŸ—£ Public speaker β€’ 🌏 Remote worker

Discussion

markdown guide
 

I have added husky + commitizen + commitlint to our projects and it has been great.

Some benefits include an auto-generated change log. auto-incrementing semantic versioning. and increased visibility for breaking changes.

I would recommend it for every project.

Because we are using gitlab, we are using these packages semantic-release-gitlab and npm-publish-git-tag.

 

woaw those 2 libraries looks great! Thanks for sharing!

 

Wow! Thank you for this. Got it up and running yesterday, I'm loving it.

 

I've used Conventional Commits before but am not a fan of the prefix approach. It often seems arbitrary and makes a git log --oneline less readable. We can accomplish the same with imperative mood english, just as git itself does.

For instance, rather than writing:

feat(template): add a favorite color option

You could instead write:

Add favorite color option for template

You could even remove the scope part as if your project is well organized the changed file should convey this same information.

This is human parseable and machine parseable. We both understand that a subject that starts with "Add" is a feature. You can extend that with regex validation for the other types. The subject can be directly copied into a changelog without stripping prefixes

Examples of git's own messages:

Revert "x"
Merge "x"

chris.beams.io/posts/git-commit/

 

We both understand that a subject that starts with "Add" is a feature

Depends. This is not standardised. You may not have the same understanding of your colleague

About the scope, I agree. In small project, it's not necessary. THat's why this field is optional btw.

 

By "we" I meant machine and human. To ensure complete understanding among peers I agree a simple spec (which would likely be an extension of conventional commit) is in order. Even among the "example" repositories for conventional commit many commits do not follow the spec (i.e. Merge ...). Among other projects such as Deno, I see some commits by maintainers that do not follow the prefix approach as it is more clear without it.

Almost every feat commit I see in the wild starts out as "feat: add" so the prefix is redundant for machines here and a changelog generator should work with or without the prefix.

Even among my monorepos I found scope annoying though I added it habitually it doesn't really add to clarity much. So I'm glad it is optional.

 

I am trying to use the semantic commit messages, but find it difficult to categorize some commits. What type would you on changing a configuration variable, say the password for a database?

 

hey Joyce.
I'm now using semantic commit messages with semantic release.

  • fix: I'm fixing a bug. Patch release
  • feat: I'm adding a feature. Minor release.
  • whatever+BREAKING CHANGE. I'm breaking compatibility. Major release.
  • chore: everything that does not impact the user of my app/website.

If you're changing the password in a db, I'd use the chore keyword.
After feel free to add/remove keywords. For instance, in my blog, I added the post keyword for everything related to blogposts!

I hope it helps you :)

 

Thank you for your response.

I am using this for an internal project (web application), so the concepts of release and breaking changes does not apply in my case. I am using chore as of now.

Some projects restrict chore type to commits that does not cause a production code change.

 

I'm a really big fan of conventional commits! Haven't seen the perf: before but I like it a lot. Thanks for the nice article πŸ˜„

 

thank you!
About the perf it's up to you. Feel free to add/remove keywords according to your project. For instance, in my personal blog I added the post keyword when I add a blogpost!

 

This is a good idea, also you can provide git hooks (client side or even better server side) to validate the formatting of the message and automatically reject commits that don't follow this rule.

 

Hey! Nice post.

What do I write in the commit message if it's a CSS update. chore(css): updated btn-theme?

 

Hey Sanjeev! Thank you!

Well it depends!
Is this color change a:

  • bug fix? ie. an oversight from a previous commit...
  • a feature? ie. you added a new theme in your website...
  • a refactor? ie. you decided change the css classes...