Back to Oh My Posh

Conventional Commit

.agents/skills/conventional-commit/SKILL.md

30.4.04.2 KB
Original Source

Conventional Commit

Commit Message Structure

text
<type>(<scope>): <description>

[optional body]

[optional footer(s)]

Types

TypeWhen to use
featA new feature
fixA bug fix
docsDocumentation changes, no code
styleFormatting, missing semicolons, etc. (no logic change)
refactorCode change that is neither a fix nor a feature
perfPerformance improvement
testAdding or correcting tests
ciCI configuration changes
choreMaintenance tasks (updating deps, tooling, etc.)
revertReverts a previous commit

Append ! after the type/scope to signal a breaking change: feat!: or feat(api)!: When a change breaks existing behavior, both markers are mandatory: the ! suffix on the type and the BREAKING CHANGE: footer. They always appear together — never one without the other.

Scope

Optional. Use the name of the area affected, e.g., segment, cache, config, ui. Omit when the change is truly cross-cutting.

Description

  • Required. One short imperative sentence, no period at the end. The full header line (type + scope + description) must be 72 characters or fewer. Aim for 50 characters or fewer for the description itself — this almost always keeps the full header within budget regardless of type and scope length.
  • Use the imperative mood: "add", not "added" or "adds". Never past tense or present-third-person: ✗ added, fixed, bumped, implemented → ✓ add, fix, bump, implement.
  • Never mirror the input's phrasing. If the request uses past-tense words (updated, added, bumped, was removed, got regenerated), convert them to imperative before writing the description: update, add, bump, remove, regenerate.

Body

Optional. Add context about why the change was made, not what. The diff shows that. Wrap at 72 characters.

Use for:

  • BREAKING CHANGE: <description> (required when ! is used; explains the break).
  • Issue references: Closes #123, Fixes #456.
  • Co-authors: Co-Authored-By: Name <email>.

Workflow

  1. Run git status to review changed files.
  2. Run git diff and git diff --cached to inspect staged and unstaged changes.
  3. Identify the type from the table above. Ask yourself: does this change remove, rename, or alter existing behavior that callers depend on? If yes → it is a breaking change: use ! after the type/scope and add a BREAKING CHANGE: footer. Both markers are always required together.
  4. Identify the scope from the files/area changed.
  5. Write a short description in the imperative mood.
  6. Add a body if the why needs explanation.
  7. Add a footer for breaking changes or issue references.
  8. Stage the relevant files explicitly (avoid git add -A).
  9. Commit with a message that preserves multi-line formatting when body/footer are present.

Examples

text
feat(segment): add Ramadan segment with Aladhan API
fix(cache): always store mod time
docs(readme): update installation instructions
refactor(config): simplify option parsing logic
chore(deps): bump github.com/shirou/gopsutil/v4
feat(segment)!: rename template property StartTime to Start

BREAKING CHANGE: template strings using .StartTime must be updated to .Start

Validation Checklist

  • Type is one of the allowed values in .commitlintrc.yml
  • The commit message respects the rules defined in .commitlintrc.yml
  • Scope (if present) reflects the actual area changed
  • Description is imperative mood, no trailing period
  • Full header line (type + scope + description) is 72 characters or fewer
  • Both ! after type/scope and BREAKING CHANGE: footer are present whenever the change breaks existing behavior
  • No sensitive files staged (.env, credentials, etc.)