Skip to content

Instantly share code, notes, and snippets.

@qoomon
Last active December 15, 2025 10:37
Show Gist options
  • Select an option

  • Save qoomon/5dfcdf8eec66a051ecd85625518cfd13 to your computer and use it in GitHub Desktop.

Select an option

Save qoomon/5dfcdf8eec66a051ecd85625518cfd13 to your computer and use it in GitHub Desktop.
Conventional Commits Cheatsheet

Conventional Commit Messages starline

See how a minor change to your commit message style can make a difference.

git commit -m"<type>(<optional scope>): <description>" \
  -m"<optional body>" \
  -m"<optional footer>"

Note

This cheatsheet is opinionated, however it does not violate the specification of conventional commits

Tip

Take a look at git-conventional-commits ; a CLI util to ensure these conventions, determine version and generate changelogs.

Commit Message Formats

General Commit

<type>(<optional scope>): <description>
empty line as separator
<optional body>
empty line as separator
<optional footer>

Initial Commit

chore: init

Merge Commit

Merge branch '<branch name>'

Follows default git merge message

Revert Commit

Revert "<reverted commit subject line>"

Follows default git revert message

Types

  • Changes relevant to the API or UI:
    • feat Commits that add, adjust or remove a new feature to the API or UI
    • fix Commits that fix an API or UI bug of a preceded feat commit
  • refactor Commits that rewrite or restructure code without altering API or UI behavior
    • perf Commits are special type of refactor commits that specifically improve performance
  • style Commits that address code style (e.g., white-space, formatting, missing semi-colons) and do not affect application behavior
  • test Commits that add missing tests or correct existing ones
  • docs Commits that exclusively affect documentation
  • build Commits that affect build-related components such as build tools, dependencies, project version, CI/CD pipelines, ...
  • ops Commits that affect operational components like infrastructure, deployment, backup, recovery procedures, ...
  • chore Commits that represent tasks like initial commit, modifying .gitignore, ...

Scopes

The scope provides additional contextual information.

  • The scope is an optional part
  • Allowed scopes vary and are typically defined by the specific project
  • Do not use issue identifiers as scopes

Breaking Changes Indicator

  • A commit that introduce breaking changes must be indicated by an ! before the : in the subject line e.g. feat(api)!: remove status endpoint
  • Breaking changes should be described in the commit footer section, if the commit description isn't sufficiently informative

Description

The description contains a concise description of the change.

  • The description is a mandatory part
  • Use the imperative, present tense: "change" not "changed" nor "changes"
    • Think of This commit will... or This commit should...
  • Do not capitalize the first letter
  • Do not end the description with a period (.)
  • In case of breaking changes also see breaking changes indicator

Body

The body should include the motivation for the change and contrast this with previous behavior.

  • The body is an optional part
  • Use the imperative, present tense: "change" not "changed" nor "changes"

Footer

The footer should contain issue references and informations about Breaking Changes

  • The footer is an optional part, except if the commit introduce breaking changes
  • Optionally reference issue identifiers (e.g., Closes #123, Fixes JIRA-456)
  • Breaking Changes must start with the word BREAKING CHANGE:
    • For a single line description just add a space after BREAKING CHANGE:
    • For a multi line description add two new lines after BREAKING CHANGE:

Versioning

  • If your next release contains commit with...
    • Breaking Changes incremented the major version
    • API relevant changes (feat or fix) incremented the minor version
  • Else increment the patch version

Examples

  • feat: add email notifications on new direct messages
    
  • feat(shopping cart): add the amazing button
    
  • feat!: remove ticket list endpoint
    
    refers to JIRA-1337
    
    BREAKING CHANGE: ticket endpoints no longer supports list all entities.
    
  • fix(shopping-cart): prevent order an empty shopping cart
    
  • fix(api): fix wrong calculation of request body checksum
    
  • fix: add missing parameter to service call
    
    The error occurred due to <reasons>.
    
  • perf: decrease memory footprint for determine unique visitors by using HyperLogLog
    
  • build: update dependencies
    
  • build(release): bump version to 1.0.0
    
  • refactor: implement fibonacci number calculation as recursion
    
  • style: remove empty line
    

Git Hook Scripts to ensure commit message header format

Click to expand

commit-msg Hook (local)

pre-receive Hook (server side)

  • create following file in your repository folder .git/hooks/pre-receive
    #!/usr/bin/env bash
    
    # Pre-receive hook that will block commits with messages that do not follow regex rule
    
    commit_msg_type_regex='feat|fix|refactor|style|test|docs|build'
    commit_msg_scope_regex='.{1,20}'
    commit_msg_description_regex='.{1,100}'
    commit_msg_regex="^(${commit_msg_type_regex})(\(${commit_msg_scope_regex}\))?: (${commit_msg_description_regex})\$"
    merge_msg_regex="^Merge branch '.+'\$"
    
    zero_commit="0000000000000000000000000000000000000000"
    
    # Do not traverse over commits that are already in the repository
    excludeExisting="--not --all"
    
    error=""
    while read oldrev newrev refname; do
      # branch or tag get deleted
      if [ "$newrev" = "$zero_commit" ]; then
        continue
      fi
    
      # Check for new branch or tag
      if [ "$oldrev" = "$zero_commit" ]; then
        rev_span=`git rev-list $newrev $excludeExisting`
      else
        rev_span=`git rev-list $oldrev..$newrev $excludeExisting`
      fi
    
      for commit in $rev_span; do
        commit_msg_header=$(git show -s --format=%s $commit)
        if ! [[ "$commit_msg_header" =~ (${commit_msg_regex})|(${merge_msg_regex}) ]]; then
          echo "$commit" >&2
          echo "ERROR: Invalid commit message format" >&2
          echo "$commit_msg_header" >&2
          error="true"
        fi
      done
    done
    
    if [ -n "$error" ]; then
      exit 1
    fi
  • ⚠ make .git/hooks/pre-receive executable (unix: chmod +x '.git/hooks/pre-receive')

References


@JohnnyWalkerDigital
Copy link

JohnnyWalkerDigital commented Dec 4, 2025

Attempt at a flow chart:

Did you fix a bug?

Yes: It's fix:

No: Did you change functionality or affect UI?

Yes: It's feat:

No: Did you add or change tests?

Yes: It's test:

No: Did you change code style or formatting (doesn't affect code behaviour)?

Yes: It's style:

No: Did you make changes to documentation?

Yes: It's docs:

No: Did you change how the project is built (eg. packages, dependencies, dockerfile, etc)?

Yes: It's build:

No: Did you change something related to devops (eg. operational or deployment/CI pipelines)?

Yes: It's ops:

No: Did you complete a maintenance task or other non-code task for the project (eg. modifying .gitignore or making initial commit)?

Yes: It's chore:

No: Did you rewrite or restructure code specifically for performance?

Yes: It's perf:

No: It's refactor:

@ttytm
Copy link

ttytm commented Dec 5, 2025

@JohnnyWalkerDigital

Attempt at a flow chart:

[...]

Did you fix a bug?

Yes: It's fix:

No: Did you change functionality or affect UI?

Yes: It's feat:

No: Did you add or change tests?

Yes: It's test:

No: Did you change code style or formatting?

Yes: It's style:

No: Did you make changes to documentation?

Yes: It's docs:

No: Did you change things related to build or deploy operations?

Yes: It's build:

No: Did you change something related to devops, infrastructure or backups?

Yes: It's ops:

No: Did you complete a maintenance task or other non-code task for the project (eg. modifying .gitignore or making initial commit)?

Yes: It's chore:

No: Did you rewrite or restructure code specifically for performance?

Yes: It's perf:

No: It's refactor:

I think using a flowchart makes the solution more complicated.
AFAIK GitHub renders mermaid diagrams, so it should become visible here:

flowchart TD
    A[Did you fix a bug?]
    A -- Yes --> B[It's fix]
    A -- No --> C[Did you change functionality or affect UI?]

    C -- Yes --> D[It's feat]
    C -- No --> E[Did you add or change tests?]

    E -- Yes --> F[It's test]
    E -- No --> G[Did you change code style or formatting?]

    G -- Yes --> H[It's style]
    G -- No --> I[Did you make changes to documentation?]

    I -- Yes --> J[It's docs]
    I -- No --> K[Did you change things related to build or deploy operations?]

    K -- Yes --> L[It's build]
    K -- No --> M[Did you change something related to devops, infrastructure or backups?]

    M -- Yes --> N[It's ops]
    M -- No --> O[Did you complete a maintenance task or other non-code task?]

    O -- Yes --> P[It's chore]
    O -- No --> Q[Did you rewrite or restructure code specifically for performance?]

    Q -- Yes --> R[It's perf]
    Q -- No --> S[It's refactor]
Loading

Since every decision is a simple yes/no that ends in exactly one category, a decision table (or ordered checklist) is likely a better fit.

Checklist attempt based on the order of the original answer

  1. If it fixes a bug → fix
  2. Else if it changes functionality or UI → feat
  3. Else if it adds or changes tests → test
  4. Else if it changes code style or formatting → style
  5. Else if it changes documentation → docs
  6. Else if it affects build or deploy → build
  7. Else if it affects devops, infrastructure, or backups → ops
  8. Else if it’s a maintenance or non-code task → chore
  9. Else if it improves performance → perf
  10. Else → refactor

Table attempt based on the order of the original answer

Question If Yes → Use Type
Fixes a bug? fix
Changes functionality or UI? feat
Adds or changes tests? test
Code style or formatting only? style
Documentation only? docs
Build or deploy related? build
DevOps / infra / backups? ops
Maintenance or non-code? chore
Performance-focused change? perf
Otherwise refactor

Table attempt with structural improvement

While the order in your answer is already a strong foundation. I think the priority order can be improved. Attempt below trying to match the current conventional Commit semantics:

Question If Yes → Type
Bug fix? fix
New or changed feature in API/UI? feat
Performance improvement? perf
Code restructuring without behavior change? refactor
Formatting only? style
Tests added/corrected? test
Documentation only? docs
Build tools, dependencies, versions? build
DevOps, infrastructure, or backups? ops
Anything else chore

Overall the intent here is minimizing mental load, improve long-term consistency, use chore as true fallback to preventing it's lazy overuse.

@AchiraNadeeshan
Copy link

correct typo "I case" to "In case" in commit message description rules.

@JohnnyWalkerDigital
Copy link

Personally I find ops: to be unnecessarily detailed with little benefit over using build:. I also think perf: is unnecessary... the description of a refactor: can indicate performance improvements.

@qoomon
Copy link
Author

qoomon commented Dec 15, 2025

@AchiraNadeeshan thanks, I fixed it

@qoomon
Copy link
Author

qoomon commented Dec 15, 2025

I also think perf: is unnecessary... the description of a refactor: can indicate performance improvements.

You don't have to use perf:, however it can be handy for generating changelogs automatically because in general refactoring: commits (especially those that only improves code readability) are not worth mentioning in a change log for users except performance improvements

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment