Subete commit system¶
Status
Whole page reflects both branches.
Commit messages are hard to think of in a clever and consistent way, which is why standard rulesets to aid with the thought process are used. Usually, Conventional Commits is used, as it is widely considered a perfect standard, but we at Subete developed our own standard aimed at improving this system.
A Subecommit (short for "Subete Commit System compliant commit", or equivalent to "Conventional Commit"/"Conventional Commits compliant commit") looks as follows:
Where:
!: signifies a breaking change. This must be explained in the commit’s long description.type: the type of the commit, there is a standard list of nouns to choose from (which projects may choose to extend).@scope(optional): the area of the codebase the commit targets: a class or method name, file name, or software feature. You can concatenate scopes with a plus sign (+).ptN: a part signaler. If a commit is made without all of the work relative to its goal is unfinished, rather than using nonstandard conventions like WIP, 1/n and so on, we standardized on usingpt1,pt2and so on.- If steps can be split into sub-steps, parts should be split into subparts (as in
pt1.1,pt1.2and so on). - When a commit is known to be the final part of a series, it should signal that with a dot (as in
pt3.). - If after a series finale additional work is needed (because, for example, a mistake was found now), the series shall continue using an exclamation (as in
pt3.1!orpt4!). A lesser serious but still normative variant is to use the "dlc" word as a second part signaler, starting again from 1 (as inpt3 dlc1). ptand part are equally compliant, butptis preferred (due to less typing).description(and>): a one-line summary of the changes. It can't exceed 50 chars, use an extended description for that. Add a greater than (>) symbol to indicate there's an extended description (note this reduces effective max commit length to 48).extended description: the aforementioned. If a single commit does several changes, it should list out every individual change in the same format (but without the 50 char limit). It may also contain regular descriptive text. If mixing both, the description goes before the individually listed "commits".tags: key-value pairs providing parseable information, if needed. These can indicate issues this commit resolves, the coauthors, the breaking changes, etc. The keys are standardized and should be enclosed by brackets too.
You must use this with everything, even with Git features. When doing a merge commit, update its message to be like so:
Similarly, other features like [rebase] or [revert] get their commits in this format.
Supported commit types are:
fix: fixes an issue of any kind with the softwarefeat: adds a new feature or capability to the softwareperf: improves performance of the software with no other change attacheddoc: alters documentation of the software in any wayrefactor: improves, refactor or rewrites source code of the software without changing behaviorci: modifies CI/CD pipelines or anything directly related to themchore: takes care of miscellaneous chores for the repositorylegal: updates to ToS/Privacy Policy; usually not on this repo (as these are in SokoraDesu/Legal), though changes made to the bot or the text it shows that are caused by a change to these do have to use this tag- Additionally, Git features that imply a commit on their own are valid as commit tags (e.g.
rebase,merge, etc...).
Supported tags are:
[!]: to explain breaking changes. Required for every breaking change you make in a commit.[Co-authors]: to credit coauthors. List them and follow theName <@username>format. Name should be the display name they wield on their GitHub profile, and username should be their GitHub username.[Closes]: to mention issues this resolves. List them providing the #number identifier of the issue.[Clankers]: to mention any AI model that has touched the commit, if any. List them using aprovider/model-name-and-versionformat (an OpenRouter string works).
Examples¶
Minimal commit
Scoped commit, part of a commit chain
Long commit
[refactor] migrate to ES syntax >
changes all existing code to use ECMAScript syntax (import, async/await, etc.) rather than CommonJS (require, callback, etc.), making this more standard-compliant
Breaking change!
![fix@settings pt2.] setting handler fixed
Note that setting useFoobar was renamed to enableFoobar to match all other keys.
Breaks previous configurations.
Continued-after-finale commit series
Someone clearly losing their mind
[!TIP] There is no limit to how many times you can reopen a "finished" series. So what you're seeing above is normative commit-wise, but it signals something not as normative is happening with the development process.
Incorrect examples¶
Examples of non-normative commits. These break the rules!
Standard tag misuse
feat is for use with new features within the software that is being developed, not within its codebase. this commit should be using refactor.
Breaking the chain
[feat pt1] add Windows ARM support
Initial commit adding the build targets and stuff. Code patches for it to work will follow.
[feat pt3] add Windows ARM support
Updated build scripts so it actually compiles.
Cannot skip a number!
Using more exclamations than appropriate
[refactor pt3.] use XDG Portals for all features possible
[refactor pt4!!!] use XDG Portals for all features possible
broke something, oops!
Exclamations are to be used linearly. You cannot just use more than what it corresponds.
Frequently Asked Questions¶
Is there a way to avoid using parts for related commits?
Short answer: No.
Long answer: Group your changes. Parts are used for several commits that target the same goal, e.g. adding a specific feature (where pt1 could be a needed refactor and pt2 the actual implementation). Grouping everything makes this go away, though it is considered a bad practice (the more atomic a commit is, within fair limits, the better).
What if I really can't fit the short description in 48 chars?
Short answer: Your commit probably does too much.
Long answer: Check the writing is duplicating nothing. A common mistake is [fix] fixed … where the verb does the tag's job. Another mistake is, when a commit does many things, trying to find shorter terms to describe the contents of the commit; if it doesn't fit, just leave that for the extended description and limit the short description to what the commit touches. E.g., [fix] cart page + password validation >, and then the extended description tells what the actual fixes are.