Clean git history is essential because it helps to make it easier to understand the evolution of a project. When history is cluttered with unnecessary commits and merge conflicts, it can be challenging to understand what changes were made and why they were made. A clean history can also make it easier to revert to previous versions of the project, as it is easier to find specific commits when the history is organized.
Overall, a clean git history is essential for the maintainability and understandability of a project.
A bad git history can take many forms, but some common characteristics include the following:
In general, a horrible git history is challenging to understand and navigate. It may also indicate poor coding practices, such as a lack of testing or focus on code organization.
Here are some examples of what I consider lousy git commit messages:
Good git commit messages follow a few best practices:
Here are some examples of good commit messages:
In general, good commit messages are specific and informative and help provide context about the changes that were made. This makes it easier for others to understand the project's evolution and collaborate effectively.
Conventional commits are a structured way of writing commit messages that makes it easier to generate changelogs, release notes, and other documentation automatically. The goal of using conventional commits is to make it easier to understand the changes that have been made to a project and to allow tools to understand the intent of each commit more easily. Those things work because the way the commit messages are written is predictable. That also means humans can easily read and understand them.
Several conventions for formatting commit messages have been established as best practices. One widely used convention is the Angular convention, which defines the following structure for commit messages:
The type is a short, all-lowercase string that describes the nature of the commit. Some common types include:
feat: New feature for the user (not a part of the code, or ci, ...)
fix: Bugfix for the user (not a fix to build something, ...)
docs: Changes to the documentation
style: This could be the code's styling or general styling changes. Does not change any functionality.
refactor: Refactoring production code. For example: Renaming a variable
test: Only changes current or new tests. Does not change the production code
chore: Does not impact production.
The scope is an optional string that describes the part of the codebase that the commit affects.
The subject is a brief description of the changes made in the commit. It should be written in an imperative mood and should not exceed 50 characters.
For example, a commit message following the Angular convention might look like this:
feat(search): add support for searching by date range
The body of a conventional commit is optional and is used to provide a more detailed description of the changes made. It should be used to explain the motivation for the changes, as well as any implementation details that may be relevant.
The body of the commit should be separated from the subject by a blank line and wrapped to a maximum line length of 72 characters.
Here is an example of a commit message with a body:
feat(search): add support for searching by date range This commit adds a new feature to the search module that allows users to search for records within a specific date range. The date range can be specified using two new fields on the search form: a start date and an end date. - Adds new fields to the search form for specifying the date range - Updates the search API to accept the start and end dates as parameters - Modifies the search results page to display the selected date range
In general, the body of a commit message should provide enough information to understand the changes and motivations behind them without going into unnecessary detail.
In conventional commits, breaking changes are indicated by including the word "BREAKING CHANGE" in the commit message, followed by a colon and a description of the breaking change.
feat(search): add support for searching by date range BREAKING CHANGE: The search API now requires a start and end date to be specified for all searches. The old API, which only accepted a single search term, is no longer supported. This commit adds a new feature to the search module that allows users to search for records within a specific date range. The date range can be specified using two new fields on the search form: a start date and an end date. - Adds new fields to the search form for specifying the date range - Updates the search API to accept the start and end dates as parameters - Modifies the search results page to display the selected date range
The description of the breaking change should explain the change's impact and any steps users will need to take to migrate to the new version.
You can also append '!' to the scope/type to get the same result:
feat(search)!: add support for searching by date range
fixpatches a bug in your codebase (this correlates with PATCH in Semantic Versioning).
featintroduces a new feature to the codebase (this correlates with MINOR in Semantic Versioning).
feat(scope): add magical unicorn ^--^^-----^ ^------------------^ | | | | | +-> Summary in present tense. Starting with add, remove, update, do. Think about: If I commit this, my code would .... add magical unicorn | | | +-> optional scope of the commit, component-name, container | +-------> Type: chore, docs, feat, fix, refactor, style, or test.
Read more related articles