6  Commits

Note

This guidebook is written following the diátaxis “how-to guide” style. And because this document reflects how we work in the Seedcase Project, it is living and constantly evolving. It won’t ever be in a state of “done”.

This guide covers how we in the Seedcase Project commit changes to our repositories. By following a set of guidelines you can ensure that the commit history is clear and consistent, which allows for automatic generation of changelogs and increasing the version number of the project.

This page describes when and what to commit, the Conventional Commits specification, and how to apply it to both code and non-code projects.

6.1 When and what to commit

It’s best to follow a few guidelines for when and what you commit. In general, aim to:

  • Make atomic commits: Each commit should represent a single logical change.
  • Commit often: Make commits frequently to capture progress and changes.
  • Write short and meaningful messages: Write clear and descriptive commit messages that explain the change by following the Conventional Commits specification for the messages.

6.2 Conventional commits

Conventional Commits is a specification for writing commit messages that makes it easier to understand the history of a project and automate versioning and changelogs. To learn more about the reasons for using Conventional Commit (with Gitmoji), check out the decision post documenting it.

The Conventional Commits specification generally follows the format:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

For example:

fix: prevent overwriting existing raw files

Where:

  • <type> is the type of change.
  • [optional scope] indicates the area of the codebase affected by the change.
  • <description> is a brief summary of the change.
  • [optional body] provides additional context or details about the change.
  • [optional footer(s)] includes breaking changes or references to issues/tasks.
Tip

Do you want an easier time making Conventional Commits and you use VS Code? Then install the extension Conventional Commits to help write the messages, which also includes the emojis from Gitmoji. Adding emojis is a nice way of making the messages more expressive and visually appealing.

6.2.1 Required: type and description

The <type> in Conventional Commits is inspired by Angular’s commit message conventions and is used to categorise the changes made in the commit:

  • build: Changes that affect the build system or external dependencies.
  • ci: Changes to the CI configuration files and scripts.
  • docs: Documentation only changes.
  • feat: A new feature.
  • fix: A bug fix.
  • perf: A code change that improves performance.
  • refactor: A code change that neither fixes a bug nor adds a feature.
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc).
  • test: Adding tests or correcting existing tests.
  • revert: Reverts a previous commit.
  • chore: Other changes that don’t modify source or test files.

The <description> section is where you write a short summary of the change. Write it to be descriptive enough to understand the change without needing to look at the actual changes. Write it in the imperative, present tense (i.e., “change” not “changed” nor “changes”), not capitalized, and without a period at the end.

6.2.2 Optional: scope, body, and footer(s)

Whenever you want to expand on the <description>, you can add an [optional body] that provides more context or details about the change. This might include the motivation for the change, how it was implemented, or any other relevant information that didn’t fit in the description.

The [optional footer(s)] is used for various purposes, such as indicating breaking changes or referencing issues. The main use for this footer is to indicate a breaking change, where you would add a footer in the format BREAKING CHANGE: <description>. Whenever a breaking change is committed, you also need to add a ! after the <type> in the commit message. For example:

feat!: new feature that breaks existing functionality

BREAKING CHANGE: This feature changes the way the existing functionality
works, so it is not backward compatible.
Tip

In the Seedcase Project, we tend not to use [optional scope] too often. We mostly use it in automatic commits that are generated by tools like Dependabot.

6.3 Conventional commits for non-code projects

The Conventional Commit specification was created for software or code-related projects, but it can also be used for documentation, workshops, and other non-code projects. In non-code projects, the <type> can be adapted so that meaningful changelogs and versioning updates can still be generated automatically.

Some of the <types> are the same in documentation and other non-code projects as in software projects. The ones that are the same between code and non-code projects are build, ci, style, chore, and revert. The ones that are not relevant for non-code projects are test, perf, and docs (since documentation is often the main thing being changed). Instead, use other <types> that are more descriptive of the change being made, which are different from code projects:

  • feat: Changes that add new content.
  • refactor: Changes that modify or revise existing content, where the meaning or intent stays the same. This is used in editing or proofreading phases or tasks.
  • fix: Changes that fix typos, grammatical errors, incomplete sentences, or other similar writing mix-ups/situations where the text doesn’t align with our original intent.

As for emojis, use them in the same way as in software projects. The only emoji exception is the :memo: (📝) emoji that is used for documentation-related commits. In the same way as the docs <type>, it is redundant when almost all changes are related to documentation. Instead, use other emojis that are more descriptive of the change being made or omit the emoji altogether.