Git Better with Commitlint and Conventional Commits
Tags: git, javascript, coding, tutorial
Published: 2023-05-26 03:22:44

Writing good commit messages for projects can be challenging. When a project scales and involves many developers, inconsistencies in format and writing style can arise. We can solve this by using the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification and configuring our project with commitlint to enforce this standard.  
  
### Initialize a Project with Git  

If you have a project set up in git already that you want to add this feature to, skip ahead to the section **Configuring commitlint**. Otherwise, follow the below steps to test this feature in a new project.  
  
1. Create a new empty directory on your computer named **git_better_demo**  
2. Navigate to the **git_better_demo** directory in your terminal  
3. Run the command `git init` to initialize this directory with Git. This will create a hidden directory named **.git/**  
4. Run the command `npm init` to initialize this directory with npm. You will be prompted for details about your repository. The details you provide will be added to your package.json and can be modified later as needed. To accept all default values, press Enter through full prompt.
5. Open in your preferred IDE.  
  
### Configuring commitlint  
> **NOTE FOR WINDOWS USERS**:  
> Make sure you are in Windows PowerShell rather than Command Prompt. The following commands will not work properly when using Command Prompt. Also make sure after running the command in step 2 to create the commitlint.config.js, the file must be UTF-8 in order to work (if in VSCode, check the bottom right corner. It may say UTF-16. This can be manually adjusted).
  
#### Installing @commitlint/cli and @commitlint/config-conventional  
1. Run the command `npm install --save-dev @commitlint/config-conventional @commitlint/cli` in your terminal . This will install the commitlint command line tools and a commitlint configuration that enforces the Conventional Commits specification into your project. 
  
2. Run the command `echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js` in the terminal. This will create the file **commitlint.config.js** and sets commitlint to use the pre-configured rules from the config-conventional package
  
### Configuring Husky  
  
We will use a tool called Husky to run commitlint checks any time we use git commit  
  
1. Initialize Husky in the project by running `npx husky-init`. This will prompt you to install `husky-init`. Press enter to proceed. A hidden directory will be created in your project named `.husky`.
2. Delete the **pre-commit** file under the `.husky` directory. This will not be needed and can be added again in the future.
3. Add the **commit-msg** hook to enforce commitlint rules when using git commit by running `npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'` . This will prompt you to install `husky`. Press Enter to proceed. You should see a **commit-msg** file appear under the `.husky` directory.  
  
4. Test that the commit-msg hook is active by running `git commit -m "fail: this is a failing commit message"`. Since **fail** is an invalid type based on Conventional Commits, the commitlint will prevent you from committing with this message.  
  
This is great place to start in writing better commit messages, but this can be made even better with an interactive experience using **commitizen** and **cz-commitlint**.  
  
### Configuring commitizen with cz-commitlint  

1. Run the command `npm install --save-dev @commitlint/cz-commitlint commitizen inquirer@8`
  
2. In the `package.json`,  add `"commit": "git-cz"` under scripts.

    ```js
    "scripts": {
	    "commit": "git-cz"
    }
    ```
    &nbsp;
3. In the package.json, set up `commitizen` to use the `@commitlint/cz-commitlint` package by adding the below settings.

    ```js
    "config": {
	    "commitizen": {
		    "path": "@commitlint/cz-commitlint"
	    }
    }
    ```
    &nbsp;
4. In the terminal while still inside the project directory, run the command `npm run commit`. You should now have an interactive experience to create a commit message following the Conventional Commits specification!

### Modifying Settings
All of these settings can be modified by following the guides provided with commitlint. For example, if we decide we want to change the character limit of the **scope** to 50, open the `commitlint.config.js` file and add `"scope-max-length": [2, "always", 50]` under rules.
```
module.exports = {
  extends: ["@commitlint/config-conventional"],
  rules: {
    "scope-max-length": [2, "always", 50],
  },
};
```

This is just a small example of how to change a rule, but commitlint allows flexibility to change these settings to fit your needs.

### Summary

Commit messages play an essential role in the development process. Following a format such as Conventional Commits can help both you and your team to work in an organized manner and guide you to be more intentional with your commit messages. There are also [various other benefits](https://www.conventionalcommits.org/en/v1.0.0/#why-use-conventional-commits) in using Conventional Commits.

Happy Committing!
  
### Additional Links
[Commitlint Local Setup Documentation](https://commitlint.js.org/#/guides-local-setup)
[Commitlint Rules Documentation](https://commitlint.js.org/#/reference-rules)
[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
[Commitizen Repositories](https://github.com/orgs/commitizen/repositories)
[Commitlint Respositories](https://github.com/conventional-changelog/commitlint)