Commit message
This skill should be used when drafting a git commit message (new commit, `git commit --amend`, or a squash/rewrite message) from staged or proposed changes. It produces a user-impact subject and a concise body listing changed behaviour and breaking-change / newsfragment / related-PR pointers, deliberately avoiding motivation paragraphs (which belong in the PR description, not the commit log).From its SKILL.md
npx -y skills add Lee-W/maigo --skill commit-messageAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 14 stars14 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.8 KB, as published. Nobody here has run it
Commit Message
Consumers: any task that drafts a commit message — manual git commit, git commit --amend on an unreleased local-branch commit, squash messages, branch-rewrite scripts, agent-drafted commits.
Why this skill exists
Commit messages are the durable log a future bisecting engineer reads when something breaks years later. The reviewer reads the PR description; the future maintainer reads the commit log. They serve different audiences, and the failure mode of drafting agents is to conflate them.
Common failures:
- Body explains "why the problem existed" or "what alternatives we considered" — that is PR-description content (motivation + discussion), not durable log.
- Subject is internal-perspective (
"Initialize Dag bundles in CLI get_dag function") instead of user-impact ("Fix airflow dags test command failure without serialized Dags"). - Body forgets to leave forward pointers (newsfragment filename, related PR #, tracking issue URL) — the next reader has to do a network round-trip to recover them.
- Body bloats to 5+ lines that duplicate the PR
## Whyparagraph.git logbecomes harder to scan, not easier.
This skill encodes the short, durable style. It pairs with github-title-description: the PR body carries motivation and test plan; the commit body carries durable facts + pointers.
Inputs
- Staged / proposed diff —
git diff --staged, or the contents of the impending change if not yet staged. - Existing commit context (when amending) —
git log <base>..HEAD --pretty=format:'%h %s%n%b' --no-merges. Match the existing subject style on amend; do not change the framing just because a polish round happened. - Repo commit-style detection — does the repo enforce Conventional Commits?
pyproject.tomlhas[tool.commitizen]→ Conventional Commits expected..cz.toml/.cz.json/cz.yaml→ Conventional Commits expected.commitlint.config.js/.commitlintrc*→ usually Conventional Commits.- Repo has a documented convention that explicitly bans/avoids Conventional
Commits (e.g. apache/airflow's
AGENTS.mdbans CC-style prefixes on commit subjects and enforces it via acommit-msgprek hookcheck-no-conventional-commit-message) → follow that repo convention; stay freeform / plain-imperative there. - None of the above (no CC tooling signal, no documented ban) →
default to Conventional Commits (
<type>(<scope>): <description>). This is the maigo user's personal drafting preference for their own repos when the repo itself has no opinion either way.
So the detection order is: (1) repo has CC tooling signal → CC. (2) repo explicitly bans/doesn't use CC → follow the repo. (3) no signal either way → default to CC.
Conventional Commits type / scope reference
- Types:
feat,fix,docs,style,refactor,perf,test,chore,build,ci,revert. - Scope: lowercase, short, project-specific (e.g.
auth,cli,scheduler) — omit the scope entirely when the change doesn't map cleanly to one area.
Subject rules
- One line, ≤70 chars, user-impact framing — what changes for the user / operator / Dag author, not which files were touched.
- Match the branch's existing subject style on amend. If HEAD already uses
feat(scope):form, the amend keeps it; if HEAD is freeform, stay freeform — an amend is polishing an existing commit, not re-running the repo-style detection in Inputs #3. - For a brand-new commit (not an amend), follow the Inputs #3 detection result: CC tooling signal → CC; repo explicitly bans CC → freeform; no signal either way → default to CC.
- Verb-first ("Add", "Fix", "Allow", "Reject", "Block") is more direct than noun-first.
- No file names in the subject —
"Refactor auth.py"is bad;"Reject empty emails at signup"is good.
Bad → Good
| Bad | Good |
|---|---|
update temporal.py and tests | Support timezone in SDK temporal partition mappers |
Initialize Dag bundles in CLI get_dag function | Fix airflow dags test failure without serialized Dags |
WIP fix | Stop retry storm on 5xx from upstream |
address review comments | Reject empty emails before hashing |
Body rules
The body is for the future bisecting engineer, not the current reviewer:
- ≤3 sentences total, or equivalent in compact bullets.
- Cover only:
- What changed at the user-impact level (not the file list — the diff is right there in
git show). - Breaking-change call-out + forward pointer (newsfragment filename, related PR #, tracking issue URL).
- Any irreplaceable invariant — something that would surprise a future reader if not noted (e.g., "depends on alembic head being at <rev>", "callers must set X before calling Y").
- What changed at the user-impact level (not the file list — the diff is right there in
- Cut: "the problem existed because…" narrative, motivation paragraphs, "why we picked approach X over Y", review-history context — all of that belongs in the PR description (covered by
github-title-description). - Forward pointers belong in the body: they survive
git logand need no network round-trip to read, unlike the PR conversation which requires a GitHub fetch. - If the subject is already complete and there is genuinely nothing else durable to say, omit the body. An empty body is better than a body of restated subject.
Body anti-patterns
| Anti-pattern | Why it's wrong |
|---|---|
Repeating the PR ## Why paragraph | Duplicates content one click away in the PR; bloats git log; ages poorly |
| File list — "Refactors X, renames Y, extracts helper Z" | Internal-perspective; the diff already lists files |
| Decision narrative — "After discussion we chose A over B" | Belongs in PR review thread, not commit log |
| No body at all on a breaking change | The break + newsfragment pointer must be on the commit |
| Restating the subject as the body | Adds bytes without adding signal |
Amend vs new commit
When polishing review-driven changes on an unreleased local-branch commit, default to git commit --amend rather than stacking a "address review" follow-up commit. After amending, rewrite the subject + body in line with this skill — do not let the original "draft" message survive into the squash-merge just because nobody looked at it again.
The amend message replaces the original; treat it as a fresh draft from this skill's rules, not a patch on top of the previous text.
Output format
<subject — one line, ≤70 chars, user-impact>
<body — ≤3 sentences or compact bullets; forward pointers explicit; omit entirely if nothing durable to add>
Provide the raw text to the caller. Do not wrap in a code fence by default (the caller usually pipes it into git commit -F - or git commit --amend -F - and an outer fence breaks that). If the caller explicitly asks for a quoted form, fence it then.
When the caller presents the commit message to the user as a deliverable (rather than piping it directly to git commit), follow skills/copyable-deliverable — wrap it in a single fenced code block so the user can copy the raw text without reformatting.
Trailers
- No
Co-Authored-Bytrailer. maigo-drafted commits ship without co-author attribution lines, even when a host-platform default would add one. - 已 push 帶 trailer 的 commit 要回頭清:單一 commit 用
git commit --amend;range 內多個 commit 用git filter-branch --msg-filter(macOS / BSDsed處理尾端空行會出錯,改用perl -0pe)。清完用--force-with-leasepush,並驗 tree 內容不變、刪掉refs/original備份。
What this skill does NOT cover
- The PR description / motivation / test plan — that is
github-title-description. - Choosing what to commit (
git addstrategy, hunk staging) — caller's job. - Running
git commit— this skill only drafts text. - Conventional Commits scope taxonomy — if the repo uses CC, the caller decides the scope from the diff; this skill only mirrors the detected style.
- Multi-commit history shaping (squash decisions, rebase plans) — separate concern.