Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[RFC] A commit convention designed to make commit history more structured, greppable, and context-rich

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

standard-commits/standard-commits

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Standard Commits 0.1.0 ─ RFC

Warning

🚧 THIS DOCUMENT IS WORK IN PROGRESS 🚧

This work is currently published as a Request For Comments (RFC), feel free to give opinions and propose changes!

Note

Please notice that the emojis found in this document are only meant as a visual aid for the reader, THEY ARE NOT part of the standard.

Please notice that the collapsable sections are likely to contain meaningful parts of the standard, once again, they are collapsable just as a visual aid.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Motivation

The Standard Commits format is a structured approach to writing commit messages that enhance clarity and consistency in version control systems. This format is particularly beneficial for projects with multiple contributors, as it provides a common language for describing changes. Without getting lost in too many frills:

Why use Standard Commits?

  1. Create a history that is easily greppable and log-like
  2. Make commits context-rich so that they are easily interpretable even in the future
  3. Bring consistency even among commits of different people
  4. Let projects relying on the repo determine compatibility with new changes just by looking at the commits headers

What are the benefits of using the Standard Commits format over existing commit message formats?

The following table summarizes the main advantages of the Standard Commits format compared to other commit message formats:

Feature/Aspect Standard Commits Conventional Commits Gitmoji Commits Tim Pope Style
Grammar-based 🟢 Yes 🟢 Yes 🔴 No 🔴 No
Structured Format 🟢 High 🟡 Medium 🔴 Low 🔴 Low
Readability 🟡 Medium 🟡 Medium 🟡 Medium 🟢 High
Consistency 🟢 High 🟡 Medium 🔴 Low 🔴 Low
Greppability 🟢 High 🟡 Medium 🟡 Medium 🔴 Low
Scope Annotation 🟢 Yes 🟢 Yes 🟢 Yes 🔴 No
Reason Annotation 🟢 Yes 🔴 No 🟡 Partially 🔴 No
Importance Levels 🟢 Yes 🟡 Partially 🟡 Partially 🔴 No
Expressiveness-Length ratio 🟢 High 🟡 Medium 🟣 Top 🔴 Low
Concision 🔴 Low 🟡 Medium 🟢 High 🟣 Top

Layout

The Standard Commits format, as universally recognized, is composed of two distinct fragments: the structured (or formal) fragment and the unstructured (or expository) fragment. The former adheres to a prescribed format, ensuring clarity and consistency in commit messages. It is formally expressed as: <verb><importance?>(<scope?>)[<reason?>]. The latter expands upon the structured prefix, providing deeper insight into the modification. It consists of three elements: <summary>, <body>, and <footer>.

Each commit MUST have a <verb> and a <summary> but all the other fields are present on a case-by-case basis.

Syntax Specification

<verb><importance?>(<scope?>)[<reason?>]: <summary>

<body?>

<footer?>
🔊 verb ⚠️ importance 🔖 scope 💡 reason
add (add) ? (possibly breaking) exe (executable) int (introduction)
rem (remove) ! (breaking) lib (backend library) pre (preliminary)
ref (refactor) !!(critical) test (testing) eff (efficiency)
fix (fix) build (building) rel (reliability)
undo (undo) doc (documentation) cmp (compatibility)
release (release) ci (continuous integration) mnt (maintenance)
cd (continuous delivery) tmp (temporary)
exp (experiment)
sec (security)
upg (upgrade)
ux (user experience)
pol (policy)
sty (styling)
📝 summary ℹ️ body ⚙️ footer
Starts with a lowercase letter Starts with an uppercase letter Each tag on a new line, format: <key>: <value>
Concise and descriptive of what the change does Expands on why and how, not what (already in summary) MUST be separated from body by a blank line
MUST not repeat info from the structured fragment Organized in short, clear paragraphs Breaking: ─ describe breaking changes
50 UTF-8 characters (excluding the structured prefix) Written in imperative mood Fixes: #N ─ closes referenced issues
SHOULD use a subset of Markdown SHOULD use a subset of Markdown Co-authored-by: ─ attributes co-authorship

Example

add!(lib/type-check)[rel]: enforce type checking in function calls

Previously, the semantic analyzer allowed mismatched parameter types
in function calls, leading to runtime errors. This fix implements
strict type validation during the semantic analysis phase.

Breaking: The `validateCall` function now returns `TypeMismatchError`
  instead of returning a boolean, requiring updates in error handling.
Fixes: #247
Co-authored-by: Foo Bar <foo.bar@compiler.dev>

Structured fragment

<verb> [REQUIRED]

A <verb> describes how something has changed via an expectation. An expectation is a requirement that the code should respect. The Standard Commits format provides a set of predefined verbs to ensure consistency and clarity in commit messages, and other verbs SHOULD be avoided.

  • add (add) : Adds an expectation Introduces new content to the repository with the expectation that it SHALL behave as intended.

    add(lib/lexer)[int]: token recognition for string literals
    
  • rem (remove) : Removes an expectation Eliminates content from the repository, and consequently MUST drop all expectations associated with it.

    rem(lib/parser)[mnt]: deprecated recursive descent methods
    
  • ♻️ ref (refactor) : Maintains the expectation but changes the approach Changes approach (e.g., implementation) details while MUST maintain the same expectations about its behavior.

    ref(lib/codegen)[eff]: use hash table for symbol lookup
    
  • 🩹 fix (fix) : Makes the approach comply with expectations Corrects the approach, so that it SHALL comply with the expectations that were previously believed satisfied.

    fix(lib/parser)[rel]: handle nested function declarations
    
    Compliance details - fix

    The <reason> field MUST reflect the issue addressed by the fix.

    E.g., in the example provided the <reason> is [rel] since it fixes reliability requirements that were believed to be satisfied.

  • 🔙 undo (undo) : Undoes changes to an expectation Brings the expectation back to a previous state by reverting specific commits, ensuring that it SHALL meet the original requirements.

    undo(lib/optimizer)[cmp]: aggressive loop unrolling introduced in #a1b2c3d
    
    Compliance details - undo
    • MUST prefer undo over add or rem if the changes to revert are perfectly covered by some commits.
    • MUST prefer ref or fix over undo if the expectations SHALL remain unchanged
    • SHOULD specify the reverted commit(s) if known
  • 📌 release (release): Releases the set of expectations met Declares that a set of expectations MUST now be satisfied and ready to be publicly distributed.

    # Pre-release
    release[pre]: v1.2.0
    # Release
    release: v1.2.0
    Compliance details - release
    1. Use release when officially publishing a version — such as tagging a release, deploying, or pushing to a package registry.

    2. If you're only preparing for a release — e.g., writing the changelog, bumping internal versions, cleaning up — use [pre] as <reason>.

    3. Follow Semantic Versioning when choosing version numbers. As explained in SemVer Specification, the version MAY be prefixed with v (e.g., either 1.2.3 or v1.2.3).

<importance> [OPTIONAL]

Compliance details - omission

Implies the change MUST NOT be particularly relevant for maintainers or users.

This field is a marker that is intended to be applied only to specific commits that maintainers/users should pay attention to.

  • ? (question) : Changes something exposed externally, but not an API. It SHOULD NOT be breaking for projects that depend on the underlying repository.

    Example

    An example of a question (?) importance could be used when the output of the program shifts to a new more explicative version. For instance, changing the output from:

    Result: 7

    to

    Calculation Result: 7 (Success)

    This update does not break compatibility since the core functionality and APIs remain unchanged, but users or scripts parsing the output may notice differences.

  • ! (exclamation) : Changes an API exposed externally. It is breaking for projects that depend on the underlying repository. The <footer> MUST specify the breaking change (Breaking).

    Example

    An example of an exclamation (!) importance would be renaming or removing a public function that downstream projects rely on. For instance, changing the signature of a function from:

    pub fn calculate(a: i32, b: i32) -> i32

    to

    pub fn calculate(values: Vec<i32>) -> i32
  • ‼️ !! (loud exclamation) : This change is critical ─ previous versions have severe issues that must be addressed. Projects depending on the underlying repository SHOULD update immediately. The <footer> MUST specify the last safe commit (Last-safe-commit).

    Example

    An example of a loud exclamation (!!) importance would be fixing a severe security vulnerability or resolving a bug that causes data corruption. For instance:

    1. Fixing a bug where a memory leak causes system crashes under heavy load.
    2. Patching a security flaw that exposes sensitive user data.

<scope> [OPTIONAL]

Compliance details - omission
  • Implies the change MUST affect the entire repository.
  • Implies the enclosing parenthesis () MUST be omitted as well.
Compliance details - customization

Standard Commits does not impose any specific identifier for the scope, but it is RECOMMENDED to use a consistent naming convention throughout the project. Guidelines for naming scopes include:

  • The folder structure of the repository SHOULD NOT be used as a scope because it is not always unambiguous and can change over time.
  • The identifier MUST be in lowercase ─ e.g., lib/parser.
  • The identifiers, when composed of multiple words, MUST be separated by underscores or hyphens ─ e.g., lib/parser-json (kebab-case) or lib/parser_json (snake_case).

The scope defines what has changed. A scope MAY be a single identifier or a nested sequence of identifiers separated by a slash /.

Suggestions for common prefix identifiers include:

  • ▶️ exe : Concerns the executable

    E.g., all code that defines the command‑line interface, argument‑parsing logic, individual commands or subcommands, and any binary‑specific setup (e.g., packaging, environment bootstrapping).

  • 📚 lib : Concerns library

    E.g., modules, APIs, data models, algorithms, and business‑logic routines that can be imported by the executable or by other consumers without depending on any CLI‑specific code.

  • test : Concerns tests

    E.g., unit tests, integration tests, property‑based tests.

  • 🏗️ build : Concerns the build process

    E.g., build scripts, Dockerfiles, Makefiles, compilation flags.

  • 📓 docs : Concerns documentation

    E.g., README files, API docs, man pages, changelogs.

  • ♾️ ci : Concerns continuous integration

    E.g., GitHub Actions, GitLab CI, linter, or test workflows.

  • 📤 cd : Concerns continuous delivery

    E.g., deployment pipelines, release automation, versioning.

<reason> [OPTIONAL]

Compliance details - omission
  • Implies the reason for the change MUST not be any of the "standards".
  • Implies the enclosing brackets [] MUST be omitted as well.
  • Implies the reason for the change SHOULD be reported in the unstructured fragment.

The reason explains why something has changed. It MUST be a single identifier chosen from a predefined set of reasons.

The reasons identifiers include:

  • 🆕 int (introduction) : Introduces new functionality or components

    E.g., features, services, abstractions.

  • 🔜 pre (preliminary) : Prepares for future changes

    E.g., scaffolding, placeholders, or partial implementation. The <footer> with the Follow-up is mandatory.

  • eff (efficiency) : Improves performance or resource usage

    E.g., space/time complexity, optimizes CPU, memory, or I/O.

  • 🛡️ rel (reliability) : Improves runtime correctness

    E.g., reduces the error rate, handles edge cases, prevents crashes.

  • 🧩 cmp (compatibility) : Improves backward or cross-platform compatibility

    E.g., supports older APIs, avoids breaking changes.

  • 🛠️ mnt (maintenance) : Improves maintainability

    E.g., refactor code, simplifies the structure, removes dead code, and improves modularity.

  • tmp (temporary) : Temporary workaround or shortcut

    E.g., to be reverted, removed, or rewritten.

  • 🧪 exp (experiment) : Introduces experimental code

    E.g., exploratory changes, often reverted or iterated on later.

  • 🔒 sec (security) : Improves security or privacy

    E.g., fixes vulnerabilities, hardens authentication, prevents leaks.

  • 🆙 upg (upgrade) : Upgrades external dependencies

    E.g., bumping versions, migrating frameworks.

  • 🕹️ ux (user experience) : Enhances the final user’s experience

    E.g., better UI behavior, clearer feedback or error messages, accessibility.

  • 📑 pol (policy) : Enforces a policy

    E.g., legal compliance, internal coding standards, external specs.

  • 💄 sty (styling) : Changes formatting, naming, layout, or any purely cosmetic characteristic

    E.g., no semantic change.

Unstructured fragment

General guidelines

In all the sections of the unstructured fragment apply the following guidelines:

  1. 🧾 Use Markdown where helpful It is RECOMMENDED to use some lightweight Markdown formatting, in the following cases:
    • backticks `_` ─ to enclose identifiers
    • quotes "_" ─ to enclose words not used in their proper/most used meaning
    • unordered / ordered lists: it's RECOMMENDED to use only one style of markers (i.e. *|-|+ , 1.|1) )
    • links

    ⚠️ Warning
    Other formatting options SHOULD NOT be used.

  2. 🔍 Be as direct as possible Do not repeat information that appears in the structured fragment or previous parts of the message. Assume the reader has access to the entire commit (source files included).
  3. 🧭 Separate sections with a blank line The following sections MUST be ordered as follows and each one is separated from the next one by a blank line.

<summary> [REQUIRED]

The summary is a single-line sentence that gives a concise, human-readable description of the change. It appears immediately after the structured fragment and is separated from it by a colon (:) and a space.

To ensure clarity, consistency, and compatibility across tooling, the commit header (i.e., the first line after the structured fragment) MUST follow these rules:

  1. ✓ Start with a lowercase letter The first word of the header MUST be lowercase, unless it is a proper noun or acronym.
  2. ✏️ Phrase as a short description The header MUST be written as a concise description of what the change does.
  3. 🚫 Avoid redundancy with the structured fragment The header MUST NOT repeat information already encoded in the structured prefix (e.g., affected module, type of change, "add ...", "remove ...", ...)
  4. 📏 Limit to 50 UTF-8 characters While the summary should be as short as possible (without compromising its clarity), it SHOULD NOT exceed 50 characters. Note that this limitation applies only to the <summary>, the structured fragment is not included in the 50 characters mentioned.

<body> [OPTIONAL]

Compliance details - omission

Implies that if the <body> is omitted, and the <footer> is also omitted, then the blank line that would normally separate <summary> and <body> SHOULD be omitted as well.

The body elaborates on the summary. It provides additional context and technical details to help maintainers and contributors understand the rationale, approach, trade-offs, or limitations of the change.

It MUST follow these rules:

  1. ✍️ Use imperative mood Write as if giving instructions to the codebase:

    "Refactor logic to avoid side effects" ✅ "Refactored logic to avoid side effects" ❌

  2. 📚 Structure content clearly Write in full sentences organized into short, readable paragraphs; separated by newlines (not blank ones) and starting with an uppercase letter. Use inline code syntax (like_this) to refer to identifiers, paths, constants, or symbols. Use Markdown's unordered lists when listing examples, behaviors, or consequences.
  3. 🧠 Document rationale and tradeoffs Clearly state the reasoning behind the change. When applicable, mention tradeoffs, rejected alternatives, and known limitations of the solution.

<footer> [OPTIONAL]

Compliance details - omission

Implies the blank line separating "<body>-<footer>" SHOULD be omitted.

The footer contains structured metadata, usually meant to be parsed by external tooling.

It MUST follow these rules:

  1. 🏷️ Use standardized key-value tags Each tag appears on a new line in the format: <key>: <value>

    ⚠️ Warning
    While is NOT RECOMMENDED to use multiline values, what follows the colon (:), and lines indented under a tag MUST be treated as a unique value

  2. 📌 Commonly used tags include:
    Fixes: #N ─ references the issue or bug being resolved
    Co-authored-by: ─ attributes co-authorship
    Reviewed-by: ─ acknowledges peer review
    Signed-off-by: ─ affirms compliance with the Developer Certificate of Origin (DCO)
    Follow-up: ─ indicates work or changes that this commit is preparing for
    Breaking: ─ describes breaking changes introduced by the commit
    Last-safe-commit: ─ identifies the last known safe commit before a critical issue

Important

Future plans:

  • Regulating merges
  • Provide regexes for parsing this commit format
  • Provide customizable git hooks and CI actions to "enforce" this policy in your project
  • A customization form that will easily let users pick and communicate their choices about customization

About

[RFC] A commit convention designed to make commit history more structured, greppable, and context-rich

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  
Morty Proxy This is a proxified and sanitized view of the page, visit original site.