DEV Community

Cover image for Git Commit Patterns
Jason Hornet
Jason Hornet

Posted on

Git Commit Patterns

The use of Git for us Devs is something essential, whether in personal projects, open source with many people or an entire community.
Given that, it's important that we use git commit properly. Having a coherent and standardized language helps everyone involved in the project to understand the changes that have occurred.

Bad Commit Timeline

In the image above, we see how harmful a poorly commented commit can be, since we fail to understand the nature of the change that occurred and the context of it. In the long run, the effect is even more damaging, as the maintainability of the software suffers due to inconsistencies in the scope of these changes, and how they have affected the project in the past.

With that in mind, let's talk a little about Conventional Commits Pattern.


What Is It?

Conventional Commits is a simple convention for commit messages, which follows a set of rules and helps projects to have an explicit and well-structured commit history.


How To Use It?

The rules are very simple, as shown below we have a type of commit, the context (scope) of commit and the message (subject) of commit.

!type(?scope): !subject
<?body>
<?footer>
Enter fullscreen mode Exit fullscreen mode

Thus, ! indicates the mandatory attributes and ? indicates optional attributes.


Subject: Imperative instead of past tense

In this way we are telling our team what the commit will do if applied.

“If applied, this commit will ”

“If applied, this commit will change the markup”, which makes a lot more sense than: “If applied, this commit will changed the markup”

Commit Subject use


Type: What are the types of commits

The type is responsible for telling us what change or iteration is being made, from the convention rules, we have the following types:

  • test: indicates any type of creation or alteration of test codes.
    Example: Creation of unit tests.

  • feat: indicates the development of a new feature for the project.
    Example: Adding a service, functionality, endpoint, etc.

  • refactor: used when there is a code refactoring that does not have any impact on the system logic/rules.
    Example: Code changes after a code review

  • style: used when there are code formatting and style changes that do not change the system in any way.
    Example: Change the style-guide, change the lint convention, fix indentations, remove white spaces, remove comments, etc…

  • fix: used when correcting errors that are generating bugs in the system.
    Example: Apply a handling for a function that is not behaving as expected and returning an error.

  • chore: indicates changes to the project that do not affect the system or test files. These are developmental changes.
    Example: Change rules for eslint, add prettier, add more file extensions to .gitignore

  • docs: used when there are changes in the project documentation.
    Example: add information in the API documentation, change the README, etc.

  • build: used to indicate changes that affect the project build process or external dependencies.
    Example: Gulp, add/remove npm dependencies, etc…

  • perf: indicates a change that improved system performance.
    Example: change ForEach to While, etc…

  • ci: used for changes in CI configuration files.
    ExampleCircleTravisBrowserStack, etc…

  • revert: indicates the reversal of a previous commit.

Commit Types use

Note:

  • Only one type per commit;

  • The type is mandatory;

  • If you don’t know which type to use, it is probably a big change and it is possible to split this commit into two or more commits;

  • The difference between build and chore can be quite subtle and can lead to confusion, so we must be aware of the correct type. In the case of Node.js, for example, we can think that when there is an addition/change to a certain development dependency present in devDependencies, we use chore. For changes/additions of common dependencies to the project, and that have a direct and real impact on the system, we use build.


Scope: contextualizing the commit

At this point — and following past conventions — we managed to understand the type of change that was made in the commit (commit type) and clearly understand what the commit will bring if applied (commit subject).

Even though the scope is not mandatory, it can be used to contextualize the commit and bring less responsibility to the subject, making it as brief and concise as possible. Remembering that the scope must be inserted in the commit between parentheses.

Commit Scope use

Note: Scopes must be separated with /


Conclusion

I wrote this article in order to record one of my learnings (they were just some notes in the notion app), but I hope it can help other devs out there.

Latest comments (42)

Collapse
 
conaldev profile image
明 Conal

Really useful, thank you

Collapse
 
moritzmuecke profile image
Moritz Mücke

Our whole team is commited to these conventions. We also built a tool which creates semantic versions/releases following a ruleset. Maybe you wanna contribute or give it a shot-> github.com/AOEpeople/semanticore

Collapse
 
ashm10 profile image
Asther Marie Moreno

Awesome, thanks! 😍

Collapse
 
gizelads profile image
Gizela Delgado Soto

Great article! Thank you for sharing

Collapse
 
vyrru5 profile image
VyRru5 • Edited

idem than Hans i use gitmoji, and got poweful app on macX with raycast.com/ emoji.

Collapse
 
prakashravichandran profile image
Prakash Ravichandran

Thanks for the article.

Collapse
 
furesoft profile image
Chris

I really like the style.

Collapse
 
martialseron profile image
Martial Séron

It's a great convention but in the end, it always ends up as a squash commit with "merge branch 555-my-branch into master"

Collapse
 
spock123 profile image
Lars Rye Jeppesen

First example looked like my commits /s

Collapse
 
monjai profile image
mon-jai

Personally I prefer create a lot of commits with random name, and squashing all of them to a single, conversational commit after I have completed the task.

Collapse
 
drhyde profile image
David Cantrell

I strongly, as of a week or so ago when someone pointed it out to me, recommend not using git commit -m. It encourages terse, pithy commit messages. In the week since I've banned myself from using it (via a shell function that yells at me when I try), and enforced use of git commit -v so I can see the diff in my editor when writing them, I think my commit messages have been greatly improved.

Collapse
 
keentdev profile image
Keanu Kent B. Gargar

or you could've just enabled -v by default.

git config --global commit.verbose true

Collapse
 
drhyde profile image
David Cantrell

That won't prevent use of git commit -m though, it just turns on -v when you don't use -m to put your commit message on the command line.

Collapse
 
dikamilo profile image
dikamilo

I use Conventional Commits on a daily basis. They also play nice with semantic release than will auto version (Semantic Versioning) and generate change logs based on conventional commits.

Collapse
 
mfurmaniuk profile image
Michael

I do like this, and may have my Team do this as we have standardization around our branch names but not commits. Thanks for the brain food.

Collapse
 
thejuju profile image
Julien Gabriel

You should consider adding a reference to ticket number eventually if you work inside a team. Help a lot with code traceability.

Collapse
 
mityazima profile image
Grebenshchikov Dmitry

you can use commitizen