Conventional Commits Hygiene
Rules for atomic commits with conventional-format messages, criteria for when to split a change, and rebase etiquette for shared branches.
Use when: Use when committing work, cleaning up a branch before review, or deciding how to split a large working-tree diff into commits.
The skill file
Claude Code · SKILL.mdSKILL.md2957 chars
# Conventional Commits Hygiene
A commit is the unit of review, revert, and bisect. Each one must build, pass tests, and do exactly one thing.
## Message format
```
<type>(<scope>): <imperative summary, ≤72 chars, no trailing period>
<body: why this change, what it affects, what it deliberately doesn't do>
<footer: BREAKING CHANGE: ..., Fixes #123, Refs #456>
```
- Types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`, `build`, `ci`. Pick one — if two fit, the commit should be two commits.
- Scope is the module or area, lowercase: `feat(auth):`, `fix(parser):`. Omit it rather than invent a vague one.
- Summary is imperative mood: "add retry to webhook delivery", not "added" or "adds". Test: the summary should complete "If applied, this commit will ___".
- Body explains *why*. The diff already shows *what*. A `fix` commit body states the bug's symptom and root cause in one or two lines.
- `BREAKING CHANGE:` footer (or `!` after the type) whenever a consumer must change code or config to upgrade.
## When to split
Split the working tree into separate commits when the diff contains more than one of:
- A behavior change and a refactor that enabled it (refactor commit first, behavior second — the refactor commit's tests must pass unchanged).
- Changes to two unrelated modules.
- A dependency/lockfile bump and code changes.
- Formatting or rename noise and logic. Mechanical changes get their own commit so the logic diff stays readable.
Use `git add -p` to stage hunks selectively. Before committing, run the test suite against *exactly what is staged* — `git stash --keep-index`, test, `git stash pop` — so the commit, not the working tree, is what's verified.
## When NOT to split
One logical change spread across files (function + its test + its docs) is one commit. Don't ship a commit whose tests fail until the next commit lands.
## Rebase etiquette
- Rewrite freely on branches only you have pushed: `git rebase -i` to squash fixups, reorder, and reword *before* opening the PR. (In environments without interactive rebase, use `git commit --fixup=<sha>` then `git rebase --autosquash`, or `git reset --soft` and recommit.)
- Once a branch has reviewers, stop rewriting history mid-review — push new commits so reviewers can see what changed since their last pass. Squash at merge time instead.
- Never rebase or force-push a shared branch (`main`, `develop`, release branches). If you must force-push your own branch, use `--force-with-lease`, never bare `--force`.
- Resolve conflicts during rebase by understanding both sides; re-run the suite after every conflicted rebase before pushing.
## Pre-commit checklist
- [ ] `git diff --staged` read line by line — no debug prints, no commented-out code, no stray files.
- [ ] Build and tests pass on the staged state.
- [ ] Message type matches the diff; summary ≤72 chars, imperative.
- [ ] No secrets, no generated files that the repo gitignores elsewhere.
Install
drop into your repoSave this to your project or home directory so Claude Code can load it.
path~/.claude/skills/conventional-commits-hygiene/SKILL.md
Discussion
What people are saying
Forks
0 forks of this skillLoading forks…