First of all, why should I have to write a commit message? Git already generates a unique hash, so why is it required?
Actually, it is not required. You can make a Git commit without a message using this flag --allow-empty-message
:
git commit --allow-empty-message -m ''
However, I don't recommend you do it, even though you've already made at least one commit with a message like these:
β .
β last update
β more changes
So, what will we see here? Basically, how to make good commits. It includes message, size, and order, which are just suggestions..
At the end of this text I'll bring some tools that help us to follow this tips and write good messages.
π Let's see how to make graceful commits!
I would like to start by talking about the message, but the first step to having a good message is to define a good size for our commits.
π What's a good size for a commit?
There is no exact size, but there are some guidelines that it would be very good for you to follow:
β Atomicity: Each commit should focus on solving one specific problem or implementing something.
β Clarity and Readability: Commits should be clear and easily understandable. A commit should be self-contained and not rely on other commits to make sense.
β Frequency: Commits should be made frequently but not too often.
β Testability: The changes introduced by a commit should not break existing tests.
β Revertibility: If a commit introduces a bug or unintended consequence, it should be easy to revert the commit without affecting other parts of the codebase.
β Reviewability: Keeping commits small and focused makes it easier for team members to review code changes and provide feedback.
β Consistency: Consistency helps in understanding the development history of the codebase and makes it easier to navigate through commit logs.
Considering these ideas, there are some ways to decide how to split our commits into smaller commits. Some of these are:
Functional Changes vs Refactoring: Separate commits for functional changes (adding new features, fixing bugs) from commits that focus on refactoring or improving code quality without changing behavior. This helps in reviewing and understanding the changes more effectively.
Critical vs Non-Critical Changes: If your changes include both critical (e.g., security fixes, major bug fixes) and non-critical changes, consider splitting them into separate commits. This allows critical changes to be reviewed and deployed more quickly.
User-Facing vs Internal Changes: Separate commits that affect the user interface or user experience from commits that are purely internal (e.g., performance optimizations, code reorganization). This makes it easier to understand the impact on end-users.
I would like to talk about a pattern that I have been following, which uses a little bit of each of those. For this, I will use an example of frontend code, but it can be applied to everything.
Imagine that we are adding a feature for translation to a small application. For this hypothetical feature, I have these changes:
It's evident that there have been a very small number of changes. But I would split them into 4 commits.
1 . First with these 2 json translation files
- public/locales/en/login.json
- public/locales/pt/login.json
These files are new and not yet used in any part of our application, so they don't pose any risk. I commit them first. However, it's good to keep them separate from other new files because this code has a direct impact on the users.
2 . Second with 2 files which inserts the new package
- package.json
- package-lock.json
Keeping only these two files in this commit will make it easy to find who inserted, removed, or upgraded a package in the project.
3 . Third with 1 new file which are not imported yet
- src/i18n.ts
It is new code that is not imported by any part of our code, so it doesn't pose any risk. Additionally, it is an internal change that doesn't have a direct impact on the user.
4 . Fourth with 1 the change at the existing component
- src/App.tsx
Finally, the most "dangerous" change, where I modified an existing file. It's better to keep it separate so that in case of rollback, I only need to rollback this part.
To clarify the risk, imagine that all changes carry a certain level of risk, which is determined by their probability and severity:
Based on this, it is easier to determine which changes need to be committed separately for ease of rollback.
π What is a good message for a commit?
Now, returning to our initial question, why should I have to write a commit message?
βLogical reasoning doesn't come only from mathematics, it also comes from life.β
The same reason of our ancestors 40.000 B.C. as:
- Communication
- Learn and Teach
And the most important thing for us:
- Help someone who saw that
The message will guide and help who needs find something in our code. Sometimes it will be unimportant, and sometimes this will help recover the functional state of our product.
So for it there are some patterns which you can follow such as:
Conventional Commits
feat(service)!: add integration with xpto
Gitmoji
β¨ add integration with xpto
Atom
π¨ Add integration with xpto
Custom: You can define it as you prefer, just document it.
π [FF-666] add integration with xpto
Try using emoji as a prefix in your commit message! It can be very helpful, similar to how the trash bin is colorful and easily recognizable.
Don't you believe me? Look at the following example: try to find the commit where I π₯ remove a file!
π§ Tools to help us with commits
Finally here we have some tools to help us follow the patterns and define our messages:
- AI Commit Use AI to write the commit messages
- Copilot Configure git for use your editor with copilot and he'll help you write your commit message
- Commitizen Define a interface to write your commits and automatically and a prefix and a suffix to your message. (and others features not related)
That's all thanks for read!
Top comments (6)
To summarise
A good commit message should be concise yet descriptive, providing enough information to understand the purpose of the change at a glance. It should follow a clear and consistent format, including a succinct summary of the changes made, along with any relevant contextual details. As for the size of a commit, it's best to follow the principle of atomicity, focusing on solving one specific problem or implementing one feature per commit. This ensures that each commit remains focused and self-contained, making it easier to review, test, and revert if necessary. By adhering to these guidelines, developers can maintain a clean and understandable commit history, facilitating collaboration and code maintenance.
Wow, really helpful! I didn't know we could add emojis in commit messages.
Simple and perfect ππΏ
I love it! really useful
helpful!
There is a typo in Point 3
typo thirty it should be third
Very interesting article. Thanks for sharing it!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.