Subsystem Prefix Template
Starts the subject with the part of the codebase the change affects, followed by a colon and a short summary, such as net/http: reject invalid header values. The Linux kernel, Git, and Go all use this style. It scales well to large codebases, where "where did this change?" is often the first question a reader asks.
- Your codebase is large and organized into subsystems, packages, or components.
- You contribute to a project that uses it, such as the Linux kernel, Git, or Go.
- You want to see which area a commit touches without agreeing on a list of change types.
Template
Replace each <placeholder> by hand when you write a commit.
Lines starting with # are guidance that Git removes in its default cleanup mode.
Completed example
A fix in the HTTP package of a large codebase, with Linux kernel-style trailers.
net/http: reject header values containing NUL bytes
The server accepted header values with embedded NUL bytes and passed
them to handlers unchanged. Some proxies truncate values at the first
NUL, so the proxy and the application could read the same request
differently.
Reject such requests with 400 Bad Request, as the server already does
for other control characters.
Fixes: 1a2b3c4d5e6f ("net/http: accept obs-text in header values")
Signed-off-by: Alex Doe <alex@example.com>
Guidance
Rules
Based on Linux kernel patch guidelines. Refer to the original guide for the full convention.
- Start the subject with the affected area, followed by a colon and a space, such as
net/http:ordocs:. - Choose the prefix from where the change lives (a subsystem, package, directory, or component), and reuse the prefixes already in the history.
- Write the summary after the colon in imperative mood, without a trailing period.
- Keep the whole subject short. The Linux kernel allows 70 to 75 characters; many projects aim for less.
- Match the project's capitalization after the colon. Git and Go use lowercase.
- Use the body to explain the problem and why this solution was chosen. The Linux kernel wraps the body at 75 columns.
- Put trailers such as
FixesandSigned-off-byin the last paragraph, one per line.
Optional fields
- Nested prefixes
- Large projects nest areas, such as
net: sched:in the Linux kernel orcmd/go:in Go. Use the depth your history uses. - Body
- Needed for anything that isn't trivial. Describe the problem first, then how the change solves it.
- Fixes
- In the Linux kernel,
Fixes: <hash> ("<subject>")names the commit that introduced the bug, using at least the first 12 characters of its hash. Go usesFixes #123for issues instead. - Signed-off-by
- Certifies the Developer Certificate of Origin (DCO). Only add it when the project requires it, with
git commit -s, and only for yourself.
Common mistakes
- A prefix so broad that it says nothing, such as
misc:orcode:. - Using a full file path instead of the area, such as
src/net/http/server.go:. - Inventing a new prefix when the history already has one for that area.
- Letting the prefix replace the summary, as in
parser: fixes. - Mixing changes to unrelated subsystems in one commit instead of splitting it.
How it relates to other templates
The prefix works like a Conventional Commits scope without the type: it says where the change is, and the summary says what it does. You can combine it with other templates by keeping the prefix and using their body sections, such as those of Bug Fix or Performance Improvement. For issue references, see Issue-Linked Commit.
Use this template
Use in Tower
Tower for Mac
- Open Tower's Settings and select the Templates tab.
- Create a new template and enter the subject and body below. You can also download the template file and import it from the same tab. After importing, remove the lines that start with
#. They're guidance for Git's editor. - To use it by default, set it as the global Git value in the Templates tab, or pick it as the default commit template in a repository's settings.
- When you write a commit, click the Commit template button below the description field, or type t: or / in the subject field to choose a template.
More details: Commit Templates in the Tower for Mac documentation.
Tower for Windows
- Open Tower's Preferences and select the Templates tab.
- Click + to create a new template and enter the subject and body below.
- To use it by default, set it as the global default template, or pick it as the default in a repository's settings.
- When you write a commit, click the Commit template button in the commit composer, or type t: or / in the subject field to choose a template.
More details: Commit Templates in Tower for Windows.
Template fields for Tower
The library version with Git's # comment lines removed. If you edited the template above, copy your version from the editor instead.
Subject
<area>: <summarize the change in imperative mood>
Body
<Explain the problem this change solves and why this approach was
chosen. Wrap lines at about 72 characters.>
<Optional trailers, one per line, such as Fixes or Signed-off-by>
Use with the Git command line
Download gitmessage-subsystem-prefix.txt
The commands below assume the file is in your Downloads folder.
macOS and Linux (Terminal)
Try it once
Run this in a repository with staged changes. Git opens your editor with the template filled in:
git commit --template ~/Downloads/gitmessage-subsystem-prefix.txt
Make it the default for one repository
From the repository's root folder, save the file as .gitmessage and point Git to it:
mv ~/Downloads/gitmessage-subsystem-prefix.txt .gitmessage
git config commit.template .gitmessage
Make it your global default
Save the file in your home folder and use it for every repository without its own setting:
mv ~/Downloads/gitmessage-subsystem-prefix.txt ~/.gitmessage
git config --global commit.template "~/.gitmessage"
Windows (PowerShell)
Try it once
Run this in a repository with staged changes. Git opens your editor with the template filled in:
git commit --template "$HOME\Downloads\gitmessage-subsystem-prefix.txt"
Make it the default for one repository
From the repository's root folder, save the file as .gitmessage and point Git to it:
Move-Item "$HOME\Downloads\gitmessage-subsystem-prefix.txt" .gitmessage
git config commit.template .gitmessage
Make it your global default
Save the file in your home folder and use it for every repository without its own setting:
Move-Item "$HOME\Downloads\gitmessage-subsystem-prefix.txt" "$HOME\.gitmessage"
git config --global commit.template "~/.gitmessage"
Share it with your team
Commit .gitmessage to the repository so everyone has the same file. Sharing the file does not configure anyone's Git: Git never applies settings from a repository automatically, so each teammate runs this once in their clone:
git config commit.template .gitmessage
Inspect, change, or remove the default
# Show the configured template and where it's set
git config --show-origin --get commit.template
# Point to a different file
git config commit.template path/to/other-template.txt
# Remove the repository or global setting
git config --unset commit.template
git config --global --unset commit.template
- Templates guide, hooks enforce. A template only pre-fills the editor. To reject messages that don't follow a convention, add a commit-msg hook.
- Only the editor uses templates.
git commit -mandgit commit -Fbypass the template. - Unchanged templates abort the commit. If you save without editing the template, Git stops with "you did not edit the message".
- Comment removal depends on cleanup. Git strips
#lines under its defaultstripcleanup mode. With--cleanup=verbatim,--cleanup=whitespace, or a matchingcommit.cleanupsetting, they stay in the message. If you changedcore.commentChar,#lines aren't treated as comments. - Other commands write their own messages.
git revertandgit mergedon't loadcommit.template.
Setting up Git from scratch? The Git Config Generator builds a complete .gitconfig for you. See the git commit documentation for all options.
Use with coding agents
This skill teaches your coding agent to draft commit messages in the Subsystem Prefix format, following the published Linux kernel patch guidelines convention. It uses the library version of the template. Edits you make in the editor above aren't included.
- Follows your repository's instructions and your explicit requests first.
- Reads the staged changes and keeps unstaged work out of the message.
- Never invents motivation, issue numbers, benchmarks, or test results. It leaves placeholders and asks instead.
- Flags breaking changes and unrelated changes that should be split.
- Drafts only. It won't stage, commit, or push unless you ask it to.
Download skill commit-message-subsystem-prefix-v1.0.0.zip · Agent Skills format · MIT-0 license
Contains commit-message-subsystem-prefix/SKILL.md with the instructions, references/REFERENCE.md with the rules and a completed example, and assets/template.txt.
Install in Claude Code
- Unzip the download. It contains a single folder named after the skill.
- Move that folder to
.claude/skills/in your repository to share it with your team, or to~/.claude/skills/to use it in all your projects. - Start a new Claude Code session and ask it to draft a commit message. You can also invoke the skill directly with
/commit-message-subsystem-prefix.
See the Claude Code skills documentation for details.
Other agents
The package uses the open Agent Skills format, but we've only tested the agents listed above. For any other agent, check its documentation for skill support, or add the instructions below to its configuration file, such as AGENTS.md.
Copy the instructions
Add these instructions to your agent's configuration or your repository's AGENTS.md:
## Commit messages
Follow the Linux kernel patch guidelines convention (https://www.kernel.org/doc/html/latest/process/submitting-patches.html#the-canonical-patch-format).
```text
<area>: <summarize the change in imperative mood>
<Explain the problem this change solves and why this approach was
chosen. Wrap lines at about 72 characters.>
<Optional trailers, one per line, such as Fixes or Signed-off-by>
```
Rules:
- Start the subject with the affected area, followed by a colon and a space, such as `net/http:` or `docs:`.
- Choose the prefix from where the change lives (a subsystem, package, directory, or component), and reuse the prefixes already in the history.
- Write the summary after the colon in imperative mood, without a trailing period.
- Keep the whole subject short. The Linux kernel allows 70 to 75 characters; many projects aim for less.
- Match the project's capitalization after the colon. Git and Go use lowercase.
- Use the body to explain the problem and why this solution was chosen. The Linux kernel wraps the body at 75 columns.
- Put trailers such as `Fixes` and `Signed-off-by` in the last paragraph, one per line.
- Derive the prefix from the paths in the staged diff, and check which prefixes recent commits used for those paths (git log --oneline -- ). Reuse an existing prefix instead of creating a new one.
- If the staged changes span several unrelated areas, suggest splitting the commit instead of choosing a vague prefix.
- Match the capitalization after the colon and the subject length to recent history.
- Never add a Signed-off-by trailer unless the user asks for it. It certifies the Developer Certificate of Origin on the user's behalf.
- Only add a Fixes trailer with a hash and subject taken from git log, never from memory.
When writing a commit message:
- Base it on the staged changes (`git diff --staged`). Don't describe unstaged work as part of the commit.
- If the staged changes are unrelated to each other, suggest splitting the commit.
- Never invent motivation, issue identifiers, benchmark numbers, or test results. Keep a `<placeholder>` and ask instead.
- Call out breaking changes and include migration information supported by the changes.
- Draft the message for review. Don't stage, commit, or push unless explicitly asked.