Clean Conventional Commits
Tags: git, github, beginners, productivity
Published: 2021-10-05 15:11:25

Let’s face it, Git is a chore.  It’s about as exciting as cold oatmeal. However, when used properly, it can save millions™.

## 5 Sanity Checks For Your Commits

### Frequent 
The more often you commit, the better you track your changes and have the ability to revert if needed.  Frequent and small commits are easily merged without conflict.  It’s like saving a game, only better.

### Atomic
Atoms are small and your commits should be, too.  Don’t cram 8 hours of work into a single commit. [Atomicity](https://en.wikipedia.org/wiki/Atomicity_(database_systems)) should also apply to your commits.  Everything that’s in the commit should be related.  This allows you to easily revert without undoing unrelated changes.

### Descriptive
What’s the last thing you need when moving? Mislabeled boxes or boxes with incorrect labels.  Commits should be written in the imperative sense.  They should describe what they DO, not what they DID.

### Decentralized
Git, in its design, allows complete shared “ledgers” of changes between each clone of the repo.  The entire history of the project is kept on every machine.  As such, don’t let commits stay on your local machine.  If you have a remote repo, keep your code published somewhere else. You never know when your laptop will cache on fire, become self-aware, or worse.

### Immutable
Git gives you the “keys to the kingdom” and allows you to do any number of destructive operations to your repo.  I’ve seen bad merges go down and months of work lost from one wrong move.  As such, treat your commits as immutable.  Once they have been written, they are sealed for all eternity.  If you need to make changes, revert a commit and make a proper change.

## What are "Conventional" commits?
As Git gives you all the freedom in the world to name your branches and commits whatever you want, it’s a good idea to have a common convention for how those commit labels are authored.

Here’s the **td;lr** [(Summary)](https://www.conventionalcommits.org/en/v1.0.0/#summary)
```
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
```
Yes, commits can be multi-line and are written like emails. 99% of the time, however, you will be focusing on the first line.

### Bare minimum
`<type>[optional scope]: <description>`

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7d22ex8ohk2v7tf6rrvy.png)
 
### Scared? Don't be.

I know what you're thinking...

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwl7y72ugwwa6q8xvzqx.png)

Luckily there are tools that help this process go super smooth.

- Commitizen CLI - https://commitizen-tools.github.io/commitizen/

- VS Code Extension - https://marketplace.visualstudio.com/items?itemName=vivaxy.vscode-conventional-commits 

- Commitlint - https://commitlint.js.org/

- Other Tools - https://www.conventionalcommits.org/en/v1.0.0/#tooling-for-conventional-commits

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gc7cyytbnhptf22ilwm2.png)

### Give me the deets already.

#### Type (Required) [(Spec)](https://www.conventionalcommits.org/en/v1.0.0/#specification)

These categorize a commit and tell you what kind of change this is.  Here are examples:

* **feat** - for new features
* **fix** - for defects or bugs
* **chore** - for changes that don’t alter the source, but necessary
* **ci** - for ci pipeline changes
* **docs** - for documentation changes
* **perf** - for performance enhancements
* **refactor** - for refactors; altering the code, but not changing functionality
* **revert** - reverting changes
* **style** - for cosmetic changes
* **test** - for unit tests

#### Scope (Optional) [(Spec)](https://www.conventionalcommits.org/en/v1.0.0/#specification)
Scope allows you to box your commit into a specific feature, file, or sub-set of the application.  

```
fix(Navigation): change Loggin to Login

chore(deps): upgrade Jest to v24.5.7
```

#### Body (Optional) [(Spec)](https://www.conventionalcommits.org/en/v1.0.0/#specification)
Just like the body of an email, if you want to add more of a description to your commit, you can do so below the first line.
> Note: If the commit contains a BREAKING CHANGE, this goes in the body of the commit.
```
feat(Authentication): update cipher for better security
 
 BREAKING CHANGE all security keys will need to be regenerated and deployed.
```
#### Footer (Optional) [(Spec)](https://www.conventionalcommits.org/en/v1.0.0/#specification)

Footers are optional, but allow for ticket references to be made in the commit without clogging up the commit subject line.  The follow a specific format: 
> ..."each footer MUST consist of a word token, followed by either a :<space> or <space># separator, followed by a string value."
> [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#specification)

There are several tools that will parse commit messages and automatically make links to tickets.
```
refactor(Header): correct minor typos in code

see the issue for details

Refs: JIRA-9999
```

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05biezzxtqo6rpulzqup.png)

## FAQ [(source)](https://www.conventionalcommits.org/en/v1.0.0/#faq)

### How should I deal with commit messages in the initial development phase?

Proceed as if you’ve already released the product. Typically somebody, even if it’s your fellow software developers, is using your software. They’ll want to know what’s fixed, what breaks etc.

### Are the types in the commit title uppercase or lowercase?

Any casing may be used, but it’s best to be consistent.

Although, more often than not, lowercase is used.

### What do I do if the commit conforms to more than one of the commit types?

Go back and make multiple commits whenever possible. Part of the benefit of Conventional Commits is its ability to drive us to make more organized commits and PRs.

### Doesn’t this discourage rapid development and fast iteration?

It discourages moving fast in a disorganized way. It helps you be able to move fast long term across multiple projects with varied contributors.