Operative commit message framework
Tags: development, code, git
Published: 2023-05-20 07:47:52

The web is full of articles about "writing meaningful commits"[^1] [^2] [^3].

Here is yet another article, written by me. But, this time, I'd like to challenge the benefit of adding the description, the "what", in the commit message, and propose a different framework.

# Houston, we have a problem with commits here

If we think about our experience with the commits messages, even the well-written ones, we can spot some problems with them:
- no context
- the "what" problem
- no benefit for merge request

## No context

Putting in a commit just the description of "What" the commit does adds no context to understand the reason why the commit exists.

In the following example:

```
$ git show --pretty=fuller -s HEAD
commit 7b2f87d6174a2d2a53d03e224a25e34ba9288c43 (HEAD -> main, origin/main, origin/HEAD)
Author: 	Batman <darkknight@savethepeople.com>
AuthorDate: Mon Apr 01 00:00:00 2023 -0000
Commit: 	Batman <darkknight@savethepeople.com>
AuthorDate: Mon Apr 01 00:00:00 2023 -0000

Save user preference about candies
```

When someone else, or the developer (Batman) in the future, will re-read the comment, the historic memory about the days when the commit was issued is gone.

- Why did we need to save the users' candies preference?
- What were we doing at the time?

## The "what" problem

Going into details on the "context" problem, we fall into the "what" problem.

Writing down only "what" the commit does is just repeating something that could be read from the code. Or, in an even worst scenario, if that part of the code is gone, it will be impossible to relate the current codebase with the commit and its message.

Imagine the "candies preferences save" functionality above has been removed, we have now a completely useless commit message in our repo.

The "what" problem is also about the misalignment between the commit message and the code changes. A lazy developer didn't specify all the "what" details. The reader of the commit will have a difficult time relating some changes to the commit description.

## No benefit for merge request

When we review a merge request we have the full list of changes aggregated. We have no visibility on the changes history.

This means that having the list of "what" each commit did could be misleading. For example, a commit description is describing a change that has been reverted in the next commit. Now we're seeing them flattened and we can't recognize the commit description in the code.

Another problem related to the merge requests is that during the creation the developer should recall the job done to guide the readers. But a "lost in translation" is likely to happen, and useful details could be missing in the merge request description. The commit messages should help here.

# Overcome the problem

The proposal here is to focus the commit messages more on the context, on the "why", and "how". Ok, no one will blame you if you put also "what" you did.

The commit message template should be
```
Task reference (unrelated) / implementation
                             test
                             refactor
                             dependencies
                             docs
                             infra
                             revert
Commit context

Whys and hows

Side effects

Command line and operative details
```

For example
```
GOTHAM-42 / implementation

We're storing candies preferences for the users because it is important to comfort them with their favourite candies when we rescue them

We store candies names into a non-relational database interfacing with our gotham-memory CQRS system

Possible side effects of this implementation is that if our citizens are gluttonous about candies we can overload the writing part of our CQRS system

To enable the writing endpoint create the Kafka topic with the following command
> kafka create topic candies.cqrs
Check the topics status with this CURL call
> curl http://cqrs.gotham.dev/write/check
```

In the header, we specify the task identifier (Jira-like in the example) to recall the specific task when the branch is gone or if the team is working [trunk based](https://trunkbaseddevelopment.com/).

In the header, we can specify also the type of the commit (special credits to [^1]):
- `implementation` refers to a feature build
- `test` we're providing some tests
- `refactor` the commit contains refactor and code improvements
- `dependencies` the commit is updating the project dependencies
- `docs` update the project documentation
- `infra` modify the infra setup for the project, i.e. database configuration
- `revert` undo some changes done in previous commits

We can also combine multiple types (`implementation + refactor`), even though a commit should be smaller and address a single type of implementation. The only exception is represented by `implementation + test` for obvious reasons.

In the bottom of the commit message are specified some operative commands that the developer has fresh in his mind and could help in bug fixing, core review, and writing READMEs and documentation.

Using this framework, when we look back at the commit, we can read the code having in mind the goal of the implementation and how we did it.

We can also be aware of some side effects and, in case of problems, we can easily identify the commit.

## Open a merge request

When opening the merge request if we list several commits following this framework we can immediately identify which commits have been reverted, and we can read the implementation flow instead of recalling it from our brain.

In this way, to fully describe the merge request we just need to rework a bit the commit messages list and side-effects and implementation details are already there for reviewers.

# Wrap up

The goal of this commit message framework is to have commit messages that are active actors in development. By focusing on context our commit messages will bring meaningful content in the future, for future readers and merge request reviewers.

Commit messages following this framework are helpful also during bug fixing by listing side effects and sensitive implementations. And commit messages are active part also in writing documentation and spreading DevOps knowledge on how to operate the system.

[^1]: [How to Write Better Git Commit Messages – A Step-By-Step Guide](https://www.freecodecamp.org/news/how-to-write-better-git-commit-messages/)

[^2]: [Git Commit Messages: Best Practices & Guidelines](https://initialcommit.com/blog/git-commit-messages-best-practices#semantic-commit-messages)

[^3]: [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)