Effective management of Commit History: Conventional Commits

Joonho Yeom
hdac_rizon
Published in
5 min readFeb 15, 2020

For today’s article, I’m going to share how we progress our development. Especially since when we first started the project, we had discussions about how to leave a Commit Message. It seems like overall, many projects don’t pay much attention to the Commit Message Format while others have defined their own rules.

We have decided to introduce Conventional Commits to the project and share some of the thoughts and feelings we have heard in the process.

What is a good Commit Message?

First, we write a chunk of code in semantic units, then, take a snapshot of the chunk and save the snapshot to VCS (Version Control System). Every time one commits, one must leave an explanation comment about the commit. The Commit Message that is written is a clue to understanding the meaning of the code. It also gives insights related to the flow and direction of the project development. Given this, it makes sense that the Message should be concise and clearly explain the meaning of the code in order to facilitate the comprehension of the Commit content.

So how to write a good Commit Message? Linus Tovalds describes a good Commit Message as follow:

Header line: explain the commit in one line (use the imperative)Body of commit message is a few lines of text, explaining things    in more detail, possibly giving some background about the issue    being fixed, etc etc.The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
74 characters or so. That way "git log" will show things
nicely even when it's indented.
Make sure you explain your solution and why you're doing what you're doing, as opposed to describing what you're doing. Reviewers and
your future self can read the patch, but might not understand why a particular solution was implemented.
Reported-by: whoever-reported-it
Signed-off-by: Your Name <youremail@yourhost.com>

Example 1-Linus’ Recommendation

The Commit Message is divided into Header, Body, and Footer. In the Header, a single line summarizing the Commit is written in the form of an imperative. The body does not describe how it is implemented, but rather provides background related to the issue, the proposed solution, and explanations why you wrote this implementation. Finally, the Footer helps keep track of the Reporter and Signer.

By specifying the message format, developers should not worry about how to write a Commit Message. Instead, they encourage developers to write what the Commit Message should contain.

The way Linus’ Commit Message was written affected numerous Commit Message Formats. And, our team decided to opt for a Conventional Commits which is one of them.

What is Conventional Commits ?

A Conventional Commits is a Commit Message Specification, inspired by the Angular Commit Guidelines. The purpose of this specification is, first, to allow developers to write Commit Messages dovetailing with SemVer, then, to automatically determine the Semantic Version of a project, and finally, to automatically generate a CHANGELOG upon production release. Conventional Commit Message is written as below:

<type>(<optional scope>): <subject>
<BLANK LINE>
<optional body>
<BLANK LINE>
<optional footer>

Example 2-Conventional Commit Message Format

How to write a Message

  • fix: is used when we have backward-compatible bug fixes. The Message type relates to the Semantic Version ’s PATCH.
  • feat: This type is used when we add new functionalities in a backward-compatible manner. The Message type relates to the Semantic Version’s MINOR.
  • BREAKING CHANGE: Starting an optional Body or optional footer with the text BREAKING CHANGE: means that it will not be compatible with existing APIs. It relates to the Semantic Version ‘s MAJOR and can be applied to any Message Type. As an option, you can include ! in the Headline to notify that the Body or Footer contains a BREAKING CHANGE.
  • You can add other types than fix and feat. Commonly used [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test]. Note that you are not required to use these types. Projects can define their own set of types and set of scopes.
fix(release): need to depend on latest rxjs and zone.jsThe version in our package.json gets copied to the one we publish, and users need the latest of these.

Example 3-Conventional Commit Message Sample with optional scope

Example 3 for fix type, means change corresponds to Semantic Version’s PATCH.

chore!: drop Node 6 from testing matrixBREAKING CHANGE: dropping Node 6 which hits end of life in April

Example 4-Conventional Commit Message Sample with BREAKING CHANGE

Example 4 shows the change corresponding to the Semantic Version’s MAJOR since the body starts with BREAKING CHANGE, A! is inserted between the type and colon on the headline to indicate that the BREAKING CHANGE is in the body.

feat(docs-infra): add v8 to the version picker in the navbar(#35196)The v8.angular.io should be ready shortly.PR Close #35196

Example 5-Conventional Commit Message Sample with optional footer

Close # 123 and similar Meta-information are written in the footer as in Example 5.

Complete Specification of Conventional Commits can be found in following the link.

Advantages of Conventional Commits

Commit History of Repository using Conventional Commits
  • Types and Scopes make it easy to identify which kind of changes are being reflected in which scope by simply scanning the Commit History Tree.
  • If one writes according to the message format, developers will be able to consciously Commit and improve the overall code quality.
    * Since the message requires writing a specific Headline, it is effective to fit the meaning of the Code in one clear Commit.
    * Fixes or features must use separate Commit with different characteristics
  • Reduce the burden of managing Versioning and CHANGELOG.
    * CHANGELOG can be generated by using scripts parsing Commit Message according to type.
    * Every time developers commit, they directly record the type corresponding to the Semantic Version, minimizing versioning mistakes and eliminating the need to manually manage whether a breaking change exists or a feature has been added.

Valuable Tools to Use with Conventional Commits

  • Linter
    * Provides Lint for Commit Message
    * Can be used in Web of CLI
    * It works withAngular Commit Convention by default settings and you can customize the convention to suit you.
  • conventional-changelog-cli
    * CLI tool to generate CHANGELOG from git metadata.
  • Semantic Release
    * Tools to automate semantic-release, it works with Angular Commit Convention by default settings and you can configure the convention.

We will post additional topics in the future covering rich and diver challenges. Stay tuned :)

References

--

--