GIT Commit Messages Shareable Format

Recently I faced the requirement to create a git commit messages convention to be shared across a software developer team.

I was looking for something simple and straightforward that every developer could do easily in his/her daily basis.

Reading about it, I discovered that there’re plenty of different approaches you can use (conventional, angular, lerna, patternplate, …), so I decided to follow the conventional commits used by angualar team.

git-hooks

 

There’re other alternatives some of them different, some of them very similar.

I could see that the angular style (AKA conventional) is widely extended and adopted.

But I’d like to go a step forward.

The Motivation

My idea was that nobody would need to do any kind of specific configuration to start using this GIT commit convetion in his/her daily basis, and in the other hand, nobody could commit anything without following this new convetion.

How to achive this enforcement to follow the convention with zero configuration ?

The Tools

As you probably already know, if you’re a GIT user, GIT allows you to fire off custom scripts when certain important actions occur.

GIT hooks are a powerful and simple way of executing actions when you do a commit, push, merge or any other GIT action.

GIT offers you different type of hooks, client-side, server-side. To keep things simple I will use client-side hooks.

These GIT hooks live inside the .git/hooks/ folder inside your repo.

Wait a minute, I don’t want to create custom scripts, distribute them across my team and explain them where to put those scripts, change permissions and how to configure GIT to start using them.

So, what could we do to get the zero-conf original idea ?

NPM to the rescue

As many of you, we’re already using NPM to manage all dependencies we use in our different projects.

We’re also using it for our custom building process.

Why don’t use it to implement this GIT commit message convention ?

I found a couple of really interesting packages that will allow you to do exactly this.

Husky is a package that will allow you to automatically run custom scripts on any GIT hook without zero-configuration.

Ok, not zero-configuration, but almost. The only configuration you need is to instruct husky in which hook you want to run scripts. That configuration is just added into your package.json file.

Let’s have a look.

"husky": {
  "hooks": {
    "commit-msg": "RUN YOUR COMMAND HERE",
    "post-merge": "RUN YOUR COMMAND HERE"
  }
}

In this case we’re telling husky to run some custom commands in the commit-msg hook and in the post-merge hook.

The commit-msg hook takes one parameter, which again is the path to a temporary file that contains the commit message written by the developer. If this script exits non-zero, Git aborts the commit process, so you can use it to validate your project state or commit message before allowing a commit to go through. In the last section of this chapter, We’ll demonstrate using this hook to check that your commit message is conformant to a required pattern.

The post-merge hook runs after a successful merge command. You can use it to restore data in the working tree that Git can’t track, such as permissions data. This hook can likewise validate the presence of files external to Git control that you may want copied in when the working tree changes.

With those hooks I can do what I was looking for.

So, just add husky package into your project and you can start using GIT hooks.

Install husky and add it to your devDependencies using this command.

npm install --save-dev husky@next

After that, instruct husky, adding the custom configuration in your package.json file, as shown in this example:

"husky": {
  "hooks": {
    "commit-msg": "RUN YOUR COMMAND HERE",
    "post-merge": "RUN YOUR COMMAND HERE"
  }
}

The commit message format

Now that we have a tool that will manage for us all th GIT commits with an easy and shareable configuration across all your projects and developers, let’s eforce the same GIT commit messages style.

This time we’ll use the commitlint package.

This linter in combination with husky will allow you to enforce the style you want to apply to your GIT commit messages.

Install the package as described below:

npm install --save-dev @commitlint/{config-conventional,cli}

This command will add commitlint cli and conventional configuration to your package.json file.

After that, just instruct commitlint that you want to use conventional configuration by running this command in your project:

echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js

Commitlint allows you to use several types of configurations:

  • @commitlint/config-angular
  • @commitlint/config-conventional
  • @commitlint/config-lerna-scopes
  • @commitlint/config-patternplate
  • conventional-changelog-lint-config-atom
  • conventional-changelog-lint-config-canonical

So, with the recently created file we’ll configure commitlint to use our desired commit messages convention.

GIT Hooks + CommitLint

Below you’ll find how my package.json file looks like:

{
  "name": "git-messages-format",
  "version": "1.0.0",
  "description": "test for getting a shareable commit messages format across a dev team",
  "main": "",
  "scripts": {},
  "repository": {
    "type": "git",
    "url": "git+https://github.com/mbelchin/git-messages-format.git"
  },
  "keywords": [
    "git",
    "messages",
    "commit",
    "format"
  ],
  "author": "Moises Belchin <moisesbelchin@gmail.com>",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/mbelchin/git-messages-format/issues"
  },
  "homepage": "https://github.com/mbelchin/git-messages-format#readme",
  "dependencies": {},
  "devDependencies": {
    "@commitlint/cli": "^7.1.2",
    "@commitlint/config-conventional": "^7.1.2",
    "husky": "^1.0.0-rc.14"
  },
  "husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
      "post-merge": "npm install"
    }
  }
}

As you noticed in our devDependencies we have installed husky and commitlint and we have a husky section to decide what hooks execute (commit-msg and post-merge).

For the commit-msg, we’ll run commitlint -E HUSKY_GIT_PARAMS to enforce following our configured convention defined in commitlint.config.js file.

module.exports = {
  extends: ['@commitlint/config-conventional']
};

We will execute also the post-merge hook to be sure that everybody after pulling has the latest version of our NPM packages. By doing that you will avoid a lot of issues.

Let’s have a look and see how it works.

GIT Commit Messages Shareable Format

More info

You’ll find all the files for this example in this repository:

https://github.com/mbelchin/git-messages-format

github

Leave a comment

Create a website or blog at WordPress.com

Up ↑