Back
GitoryxGitoryx

Git Commit Conventions: Conventional Commits & Gitmoji

A consistent commit message format makes your Git history readable, enables automatic changelogs, and improves collaboration. This guide covers the Conventional Commits specification (feat, fix, chore, docs, refactor…), Gitmoji, and how to enforce standards in your team with hooks and tooling.

Intermediate11 min readUpdated

On this page

What do feat, fix and chore mean in a Git commit?

In a Git commit, feat marks a new feature, fix marks a bug fix, and chore marks maintenance work - dependency bumps, build config, tooling - that never changes production behavior. These three are the most used types of the Conventional Commits format: <type>(<scope>): <description>.

The short version

  1. 1Use the format: <type>(<scope>): <short description>
  2. 2Common types: feat, fix, chore, docs, style, refactor, test, ci
  3. 3Mark breaking changes with !: feat(api)!: remove endpoint
  4. 4Optionally add Gitmoji prefix: ✨ feat(auth): add login
  5. 5Enforce with commitlint + Husky

Why it matters

Your team's Git history looks like: 'fix', 'fix 2', 'ok now', 'update button', 'FINAL FINAL'. Nobody can tell what changed, when, or why, and generating a changelog means reading every diff manually.

Commit conventions turn your Git history into a structured, human-readable log. They enable automatic changelog generation, clear communication during code review, and a history that makes debugging and onboarding significantly faster.

Where it usually goes wrong

  • Writing vague messages like 'fix', 'update', 'wip'
  • Mixing multiple concerns in one commit without a clear type
  • Not following a convention consistently: some commits use it, others don't
  • Using emojis without a system, so they add noise instead of signal

Commit conventions, step by step

  1. Step 1: Learn the standard commit types: complete reference

    Each type has a precise meaning. Using them consistently makes git log immediately informative and enables tooling like automatic changelogs. Here is the full reference table:

    Terminal
    feat     β†’ A new feature visible to users (triggers MINOR in semver)              Examples: feat(auth): add Google OAuth login                        feat(api): expose /v2/users endpointfix      β†’ A bug fix that corrects existing behavior (triggers PATCH in semver)              Examples: fix(cart): correct item count when quantity is zero                        fix(login): prevent null crash on empty emailchore    β†’ Maintenance tasks that do NOT affect production code or public API              Examples: chore(deps): update lodash to 4.17.21                        chore(build): upgrade webpack config                        chore(.gitignore): add .DS_Storedocs     β†’ Documentation changes only - no code logic              Examples: docs(readme): add installation steps                        docs(api): document /users query paramsstyle    β†’ Formatting, whitespace, semicolons - zero logic change              Examples: style(button): apply Prettier formattingrefactor β†’ Code restructuring without adding features or fixing bugs              Examples: refactor(auth): extract token logic to service layertest     β†’ Adding or updating automated tests              Examples: test(cart): add unit tests for discount calculationci       β†’ Changes to CI/CD pipeline configuration              Examples: ci(github): add automated deployment on tag pushperf     β†’ Performance improvements              Examples: perf(images): lazy-load below-the-fold thumbnailsrevert   β†’ Reverts a previous commit              Examples: revert: feat(auth): add Google OAuth login

    Tip: When in doubt between chore and refactor: if a user or public API is unaffected and it's housekeeping (deps, tooling, config), use chore. If it's restructuring internal code logic, use refactor.

  2. Step 2: What does chore mean in a git commit?

    chore is for internal maintenance tasks that keep the project running but have no impact on the public API or end-user behavior. If a user or a consumer of your package would never notice the change, it's a chore.

    Terminal
    # Dependency updates - the most common chorechore(deps): upgrade eslint to v9chore(deps): bump react from 18.2 to 18.3# Build system and toolingchore(build): migrate from CRA to Vitechore(webpack): enable tree-shaking for prod builds# Repository housekeepingchore(.gitignore): add .DS_Store and .env.localchore(scripts): add pre-commit formatting hook# Removing dead code / cleanup (no logic change)chore: remove unused legacy auth modulechore: delete commented-out console.log calls

    Tip: A good litmus test: if you would need to mention this change in a user-facing CHANGELOG, it's probably not a chore. If it's invisible to users, it is.

  3. Step 3: Understand the Conventional Commits format

    The format is: <type>(<optional scope>): <short description>. The type is mandatory and must be one of a predefined set.

    Terminal
    feat(auth): add JWT refresh token supportfix(cart): correct item count when quantity is zerochore(deps): update lodash to 4.17.21docs(readme): add installation instructionsrefactor(api): extract user validation to separate moduletest(auth): add unit tests for token expirationci(github): add automated deployment workflowstyle(button): fix indentation in Button component

    Tip: The scope is optional but highly recommended for large codebases. It tells reviewers exactly where the change lives.

  4. Step 4: Mark breaking changes

    Add BREAKING CHANGE: in the commit body, or add ! after the type, to signal an API-breaking change. This triggers a MAJOR version bump in semantic versioning.

    Terminal
    feat(api)!: remove deprecated /v1/users endpointBREAKING CHANGE: The /v1/users endpoint has been removed.Use /v2/users instead.
    Git Commit Conventions: Conventional Commits & Gitmoji: the same workflow in Gitoryx
    In Gitoryx: Built-in Gitmoji picker: browse and insert any emoji from the commit panel in one clickHow it works
  5. Step 5: Use Gitmoji for visual commit history

    Gitmoji maps emojis to commit types. Every emoji has a specific meaning, making the log instantly scannable.

    Terminal
    ✨ feat: add dark mode toggleπŸ› fix: correct off-by-one error in pagination♻️  refactor: extract auth logic to service layerπŸ“ docs: update API referenceπŸš€ ci: deploy to production on tag push⚑️ perf: cache user preferences in localStorageπŸ”’ fix: sanitize user input to prevent XSS🎨 style: apply Prettier formattingπŸ—‘οΈ  chore: remove unused importsβœ… test: add integration tests for checkout flow

    Tip: You don't have to pick between Conventional Commits and Gitmoji: many teams use both: ✨ feat(auth): add login form

  6. Step 6: Enforce conventions with a commit-msg hook

    Use commitlint + Husky to automatically reject commits that don't follow the convention.

    Terminal
    # Install commitlintnpm install --save-dev @commitlint/cli @commitlint/config-conventional# Create configecho "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js# Add Husky hooknpx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
  7. Step 7: Generate a changelog automatically

    With Conventional Commits in place, tools like standard-version or release-please can generate a full changelog and bump the version automatically.

    Terminal
    # Install standard-versionnpm install --save-dev standard-version# Add to package.json scripts:# "release": "standard-version"npm run release# β†’ bumps version in package.json# β†’ generates/updates CHANGELOG.md# β†’ creates a git tag

Mistakes to avoid with commit conventions

Inconsistent adoption
Half the team uses conventions, half doesn't. The log becomes a mix of structured and unstructured messages.
Fix: Enforce it automatically with commitlint. A hook that rejects non-conforming messages eliminates the inconsistency.
Using `feat` for everything
Some developers use feat for bug fixes, refactors, and documentation changes because it feels more exciting.
Fix: The type must match the intent. Misusing types breaks automated changelog generation and makes the log misleading.
Using emojis without a standard
Random emojis picked on a whim add visual noise instead of useful signal.
Fix: Adopt the official Gitmoji list (gitmoji.dev) so every emoji has a consistent, shared meaning.

Commit conventions in Gitoryx

Gitoryx displays commit types as colored badges in the commit graph, so you can immediately see which commits are features, fixes, or chores without reading each message.

  • Built-in Gitmoji picker: browse and insert any emoji from the commit panel in one click
  • Conventional Commits type selector directly in the commit message input
  • Commit history shows Gitmoji emojis rendered inline next to messages
  • Integrate commitlint via a pre-commit hook: Gitoryx surfaces hook errors inline

Free plan Β· no account required Β· macOS, Windows and Linux

Commit conventions: frequently asked questions

What does chore mean in a git commit?
chore is a commit type for maintenance tasks that do not affect production code or the public API. Typical chores include updating dependencies (chore(deps): bump lodash), adjusting build tooling (chore(build): migrate to Vite), and repository housekeeping like updating .gitignore. If end users would never notice the change, it's a chore.
What is chore in git?
In Git commit conventions (Conventional Commits), chore is the type label for internal housekeeping tasks: things like dependency upgrades, build system changes, and configuration updates that have no user-visible impact. It is one of the ten standard commit types alongside feat, fix, docs, style, refactor, test, ci, perf, and revert.
What is the difference between chore and refactor in git commits?
Use chore for tasks that keep the project healthy but don't change any code logic: like updating a dependency or cleaning up .gitignore. Use refactor when you restructure or rewrite internal code without changing its external behavior. A chore is housekeeping; a refactor is code-level restructuring.
What is feat in a git commit message?
feat stands for 'feature'. It marks a commit that adds new functionality visible to users or API consumers. In semantic versioning, a feat commit triggers a MINOR version bump (e.g., 1.2.0 β†’ 1.3.0). Example: feat(auth): add Google OAuth login.
What is the Conventional Commits specification?
Conventional Commits is a lightweight specification for commit message format: <type>(<scope>): <description>. Common types are feat, fix, chore, docs, refactor, test. It enables automated changelog generation and semantic versioning.
What are all the git commit message types?
The standard Conventional Commits types are: feat (new feature), fix (bug fix), chore (maintenance), docs (documentation), style (formatting), refactor (code restructure), test (tests), ci (CI/CD changes), perf (performance), revert (reverts a commit). Teams can also define custom types.
What is Gitmoji?
Gitmoji is a convention that maps specific emojis to commit intents. For example: ✨ for new features, πŸ› for bug fixes, ♻️ for refactors. It makes the commit log visually scannable. See the full list at gitmoji.dev.
Should I use Conventional Commits or Gitmoji?
Both work well, and they can be combined: ✨ feat(auth): add login form. Conventional Commits is better for tooling (automated changelogs, semantic release). Gitmoji adds a visual layer on top. Pick one or both. Consistency matters more than which system you choose.
How do I enforce commit conventions in my team?
Use commitlint with a Husky commit-msg hook. It automatically rejects commits that don't match the configured format and shows an error message explaining the correct format.
All Git tutorials β†’
Gitoryx

Stop fighting Git. Start shipping.

Download the fast, native Git client that developers actually enjoy using.

v1.1.0 Β· macOS 12+ (Apple Silicon or Intel) Β· Windows 10+ Β· Linux x86_64