conventional-commit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseConventional Commit Skill
Conventional Commit 技能
Overview
概述
Group working-tree changes into Conventional Commits 1.0.0 units (one commit per logical unit), or rewrite recent non-conformant commit subjects in place.
Core principle: Match user intent to the right workflow — new commits vs. history rewrite — and never bypass safety with destructive flags.
Announce at start: "I'm using the conventional-commit skill to <commit / push / rewrite> these changes."
将工作区变更分组为Conventional Commits 1.0.0格式的提交单元(每个逻辑单元对应一个提交),或是就地重写近期不符合规范的提交主题。
核心原则: 将用户意图匹配到正确的工作流——新提交 vs 历史重写——绝不使用破坏性标志绕过安全检查。
启动时告知: "我将使用conventional-commit技能来<提交/推送/重写>这些变更。"
Commands
命令
| Command | Skill | Action | Operates on |
|---|---|---|---|
| | Group working-tree changes into Conventional Commits | Uncommitted (staged + unstaged) changes |
| | Same as above, then | Uncommitted changes + remote |
| | Rewrite recent non-Conformant commit subjects | Existing local history |
| 命令 | 技能 | 操作 | 作用对象 |
|---|---|---|---|
| | 将工作区变更分组为Conventional Commits | 未提交的(已暂存+未暂存)变更 |
| | 执行上述操作后,运行 | 未提交变更 + 远程仓库 |
| | 重写近期不符合规范的提交主题 | 现有本地提交历史 |
Choosing the Right Command
选择正确的命令
Run this check before doing anything:
bash
git status --short # Are there working-tree changes?
git log --oneline -10 # Are recent messages already Conventional?| Situation | Command |
|---|---|
| Working tree has changes, history is fine | |
| Working tree has changes + want to push | |
| Working tree clean, recent history is messy ("Added X", "WIP", "Fixed bug") | |
| Both: working tree dirty AND history messy | First commit ( |
Auto-routing: If the user runs bare but the working tree is clean, look at recent history. If recent commits are non-conformant, surface this and ask: "No working changes to commit. Recent history has N non-Conformant subjects — do you want to rewrite them with ?"
/conventional-commit/conventional-commit-rewrite执行任何操作前先运行以下检查:
bash
git status --short # 是否存在工作区变更?
git log --oneline -10 # 近期提交消息是否已经符合Conventional规范?| 场景 | 命令 |
|---|---|
| 工作区有变更,提交历史无问题 | |
| 工作区有变更且需要推送 | |
| 工作区干净,近期提交历史混乱(如"Added X"、"WIP"、"Fixed bug") | |
| 工作区有变更且提交历史混乱 | 先执行 |
自动路由: 如果用户执行了基础的但工作区无变更,则检查近期提交历史。如果近期提交不符合规范,告知用户并询问:"当前没有可提交的工作区变更。近期有N条不符合规范的提交主题——是否需要使用重写它们?"
/conventional-commit/conventional-commit-rewriteConventional Commits Format
Conventional Commits 格式
<type>[optional scope][!]: <description>
[optional body]
[optional footer(s)]Allowed types
| Type | Meaning |
|---|---|
| New feature (MINOR semver bump) |
| Bug fix (PATCH semver bump) |
| Documentation only |
| Formatting / whitespace; no logic change |
| Code change that neither fixes a bug nor adds a feature |
| Performance improvement |
| Adding or fixing tests |
| Build system or external dependencies |
| CI configuration files and scripts |
| Other changes that don't modify src or tests |
| Reverts a previous commit |
Breaking changes — append after type/scope (e.g. ) and/or include a footer.
!feat(api)!: drop v1 endpointsBREAKING CHANGE: ...Subject rules
- Imperative mood: "add", not "added" / "adds"
- Lowercase first word of description
- No trailing period
- Aim for ≤72 characters in the subject line
- Scope is optional but recommended when it scopes to a clear module/area
Examples
feat(parser): add ability to parse arrays
fix(ui): correct button alignment
docs: update README with usage instructions
refactor(auth): extract token validation
chore: update dependencies
feat!: send email on registration
BREAKING CHANGE: email service is now required at boot<类型>[可选范围][!]: <描述>
[可选正文]
[可选页脚]允许的类型
| 类型 | 含义 |
|---|---|
| 新功能(对应语义化版本的MINOR版本升级) |
| 修复Bug(对应语义化版本的PATCH版本升级) |
| 仅修改文档 |
| 格式调整/空白字符修改;无逻辑变更 |
| 既不修复Bug也不添加功能的代码变更 |
| 性能优化 |
| 添加或修复测试 |
| 构建系统或外部依赖变更 |
| CI配置文件和脚本变更 |
| 其他不修改源码或测试的变更 |
| 回滚之前的提交 |
破坏性变更——在类型/范围后添加(例如),和/或添加页脚。
!feat(api)!: drop v1 endpointsBREAKING CHANGE: ...主题规则
- 使用祈使语气:"add",而非"added" / "adds"
- 描述的首字母小写
- 末尾无句号
- 主题行长度尽量控制在≤72字符
- 范围为可选,但当变更明确指向某个模块/区域时建议添加
示例
feat(parser): add ability to parse arrays
fix(ui): correct button alignment
docs: update README with usage instructions
refactor(auth): extract token validation
chore: update dependencies
feat!: send email on registration
BREAKING CHANGE: email service is now required at bootWorkflow: /conventional-commit
(default)
/conventional-commit工作流:/conventional-commit
(默认)
/conventional-commitStep 1: Inspect the working tree
步骤1:检查工作区
bash
git status --short
git diff
git diff --cachedIf there are no changes → tell the user, run the auto-routing check (above), and stop.
bash
git status --short
git diff
git diff --cached如果没有变更→告知用户,执行上述自动路由检查,然后停止操作。
Step 2: Group changes into logical units
步骤2:将变更分组为逻辑单元
Read each modified file's diff and group by intent. Each group maps to one Conventional Commit. Ignore the existing staging state — staged + unstaged changes are merged and re-grouped from scratch.
Grouping rules:
- Separate from
feat— never combinefix - Separate from code changes (unless the doc is a docstring inside the same change)
docs - Tests for a new feature/fix may go with that commit, or stand alone if unrelated
- Separate /
build/ dependency updates from feature workci - Separate from
refactorfeat - Fixes in unrelated modules → separate commits per module
- Trivial whitespace inside a feature file can fold into the feature commit
Don't over-split (a one-line trivial cleanup with the feature is fine) and don't over-combine (a and must be separate commits).
featfixSecrets check — flag any of these and exclude by default unless the user explicitly confirms: , , , , , , files containing the word in the path. Warn the user; they should not be committed.
.env*credentials.**_rsa*.pem*.key*.p12secret读取每个修改文件的diff并按意图分组。每个组对应一个Conventional Commit。忽略现有的暂存状态——已暂存和未暂存的变更会被合并并重新从头分组。
分组规则:
- 将和
feat分开——绝不能合并fix - 将和代码变更分开(除非文档是同一变更中的注释)
docs - 新功能/Bug修复的测试可以与对应提交放在一起,若无关则单独提交
- 将/
build/依赖更新与功能开发分开ci - 将和
refactor分开feat - 无关模块中的Bug修复→每个模块单独提交
- 功能文件中的无关空白字符修改可以合并到功能提交中
不要过度拆分(一行无关的清理与功能放在一起是可以的),也不要过度合并(和必须分开提交)。
featfix机密检查——默认标记并排除以下内容,除非用户明确确认:、、、、、、路径中包含的文件。向用户发出警告;这些内容不应被提交。
.env*credentials.**_rsa*.pem*.key*.p12secretStep 3: Show the commit plan
步骤3:展示提交计划
Before creating any commit, print a plan and let the user object:
Plan: 3 commits
1. feat(auth): add OAuth login flow
- src/auth/oauth.ts
- src/auth/index.ts
2. fix(api): handle null response in user fetch
- src/api/users.ts
3. docs: update README with auth setup
- README.md在创建任何提交之前,打印计划并让用户确认:
计划:3个提交
1. feat(auth): add OAuth login flow
- src/auth/oauth.ts
- src/auth/index.ts
2. fix(api): handle null response in user fetch
- src/api/users.ts
3. docs: update README with auth setup
- README.mdStep 4: Create commits one at a time
步骤4:逐个创建提交
For each unit, in plan order:
bash
git add path/one path/two # explicit paths only
git commit -m "$(cat <<'EOF'
type(scope): description
optional body explaining the why
EOF
)"Rules:
- Never or
git add .— always explicit pathsgit add -A - Never ,
--no-verify,--no-gpg-sign(unless the user explicitly asks)--amend - Never add emoji or unless requested
Co-Authored-By: Claude - HEREDOC for multi-line messages so quoting stays correct
- After each commit, run to confirm only the intended files moved
git status --short
If a pre-commit hook fails: do not retry with . Investigate, fix the underlying issue (or report it), and create a fresh commit.
--no-verify按照计划顺序,为每个单元执行:
bash
git add path/one path/two # 仅使用明确的路径
git commit -m "$(cat <<'EOF'
type(scope): description
optional body explaining the why
EOF
)"规则:
- 绝不使用或
git add .——始终使用明确路径git add -A - 绝不使用、
--no-verify、--no-gpg-sign(除非用户明确要求)--amend - 绝不添加emoji或,除非用户要求
Co-Authored-By: Claude - 使用HEREDOC编写多行消息以保证引号正确
- 每次提交后,运行确认只有预期文件被提交
git status --short
如果预提交钩子失败:绝不使用重试。调查并修复根本问题(或报告问题),然后创建新的提交。
--no-verifyStep 5: Final summary
步骤5:最终总结
bash
git log --oneline -<N>(where is the number of commits made) and show it to the user.
Nbash
git log --oneline -<N>(其中是创建的提交数量)并将结果展示给用户。
<N>Worked Example
示例流程
User: 변경사항 의미 단위로 커밋해줘
git status --short →
M src/auth/oauth.ts
M src/auth/index.ts
M src/api/users.ts
M README.md
?? src/api/.env
→ Detect .env (secret) — exclude, warn
→ Group:
1. feat(auth): add OAuth login flow (oauth.ts, auth/index.ts)
2. fix(api): handle null response in user fetch (users.ts)
3. docs: update README with auth setup (README.md)
→ Show plan, wait for confirmation
→ For each: git add <paths> && git commit -m "..."
→ git log --oneline -3用户:变更사항 의미 단위로 커밋해줘
git status --short →
M src/auth/oauth.ts
M src/auth/index.ts
M src/api/users.ts
M README.md
?? src/api/.env
→ 检测到.env(机密文件)——排除并警告用户
→ 分组:
1. feat(auth): add OAuth login flow (oauth.ts, auth/index.ts)
2. fix(api): handle null response in user fetch (users.ts)
3. docs: update README with auth setup (README.md)
→ 展示计划,等待用户确认
→ 对每个组执行:git add <paths> && git commit -m "..."
→ git log --oneline -3Workflow: /conventional-commit-push
/conventional-commit-push工作流:/conventional-commit-push
/conventional-commit-pushRun the default workflow above. After every commit succeeds:
bash
git pushIf the current branch has no upstream configured:
bash
git push -u origin "$(git branch --show-current)"Never use or . If the push is rejected (non-fast-forward), stop and report — do not auto-resolve. If the push fails for any reason, surface the error and let the user decide.
--force--force-with-lease先执行上述默认工作流。所有提交成功后:
bash
git push如果当前分支没有配置上游仓库:
bash
git push -u origin "$(git branch --show-current)"绝不使用或。如果推送被拒绝(非快进式),停止操作并报告——不要自动解决。如果推送因任何原因失败,显示错误并让用户决定下一步。
--force--force-with-leaseWorked Example
示例流程
User: /conventional-commit-push
(Same workflow as default, then:)
→ git push
error: failed to push some refs (non-fast-forward)
→ STOP. Report:
"Push rejected: branch is behind origin. Run `git pull --rebase`
first, then re-push manually. I will not auto-resolve."用户:/conventional-commit-push
(执行与默认工作流相同的步骤,然后:)
→ git push
error: failed to push some refs (non-fast-forward)
→ 停止操作并报告:
"推送被拒绝:分支落后于远程仓库。请先执行`git pull --rebase`,然后手动重新推送。我不会自动解决此问题。"Workflow: /conventional-commit-rewrite
/conventional-commit-rewrite工作流:/conventional-commit-rewrite
/conventional-commit-rewriteRewrites non-Conformant commit messages in recent history. This is destructive — it changes commit SHAs. The default policy refuses to touch any commit that already exists on a remote.
重写近期提交历史中不符合规范的提交消息。这是破坏性操作——会更改提交SHA值。默认策略不会修改任何已推送到远程仓库的提交。
Step 1: Determine the rewrite range
步骤1:确定重写范围
Default base:
bash
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || true)
if [ -n "$upstream" ]; then
base=$(git merge-base HEAD "$upstream")
elif git rev-parse --verify main >/dev/null 2>&1; then
base=$(git merge-base HEAD main)
elif git rev-parse --verify master >/dev/null 2>&1; then
base=$(git merge-base HEAD master)
else
echo "Could not determine a base. Ask the user for an explicit range." >&2
exit 1
fiIf the user specifies a count (e.g. "rewrite last 5"), use as the base instead. Never use .
HEAD~5--root默认基准:
bash
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || true)
if [ -n "$upstream" ]; then
base=$(git merge-base HEAD "$upstream")
elif git rev-parse --verify main >/dev/null 2>&1; then
base=$(git merge-base HEAD main)
elif git rev-parse --verify master >/dev/null 2>&1; then
base=$(git merge-base HEAD master)
else
echo "Could not determine a base. Ask the user for an explicit range." >&2
exit 1
fi如果用户指定了数量(例如"rewrite last 5"),则使用作为基准。绝不使用。
HEAD~5--rootStep 2: Safety checks
步骤2:安全检查
Three checks must pass before rewriting in place:
Check A — Working tree clean:
bash
[ -z "$(git status --porcelain)" ]Fail → tell user to commit/stash first; stop.
Check B — HEAD attached:
bash
git symbolic-ref -q HEAD >/dev/nullFail → tell user to checkout a branch; stop.
Check C — No commit in range is on a remote:
bash
for sha in $(git rev-list "$base..HEAD"); do
if [ -n "$(git branch -r --contains "$sha")" ]; then
pushed_commits+=("$sha")
fi
doneIf is non-empty: do not silently refuse. Show the user this menu:
pushed_commitsFound N commits in <base>..HEAD whose subjects are non-Conformant.
M of them are already pushed to a remote:
abc1234 origin/main "Added User-Agent Parser"
def5678 origin/main "Fixed bug"
...
Rewriting published history breaks pulls for collaborators. Options:
1. Cancel — keep history as-is
2. Rewrite locally + force-push (destructive; coordinate with team first)
3. Cherry-pick onto a NEW branch with rewritten messages (safe; original branch untouched)
Which option? (default: 1)- Option 1 → exit cleanly
- Option 2 → require explicit phrase like "yes force push" before continuing; after rewrite, run (NEVER
git push --force-with-lease)--force - Option 3 → see "Branch-based rewrite" below
在就地重写之前必须通过三项检查:
检查A——工作区干净:
bash
[ -z "$(git status --porcelain)" ]失败→告知用户先提交/暂存变更;停止操作。
检查B——HEAD已关联分支:
bash
git symbolic-ref -q HEAD >/dev/null失败→告知用户切换到分支;停止操作。
检查C——范围内无提交已推送到远程仓库:
bash
for sha in $(git rev-list "$base..HEAD"); do
if [ -n "$(git branch -r --contains "$sha")" ]; then
pushed_commits+=("$sha")
fi
done如果非空:不要直接拒绝。向用户展示以下选项:
pushed_commits在<base>..HEAD范围内发现N条不符合规范的提交主题。其中M条已推送到远程仓库:
abc1234 origin/main "Added User-Agent Parser"
def5678 origin/main "Fixed bug"
...
重写已发布的提交历史会导致协作者拉取失败。选项:
1. 取消——保持现有历史不变
2. 本地重写+强制推送(破坏性操作;请先与团队沟通)
3. 复制到新分支并重写提交消息(安全操作;原分支不受影响)
选择哪个选项?(默认:1)- 选项1→干净退出
- 选项2→需要用户明确说出诸如"yes force push"之类的语句后再继续;重写后执行(绝不使用
git push --force-with-lease)--force - 选项3→参见下文"基于分支的重写"
Step 3: Identify non-conformant commits
步骤3:识别不符合规范的提交
For each commit in , check the subject against:
<base>..HEAD^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([^)]+\))?!?: .+Skip commits that already match. Skip merge commits (use ).
git rev-list --no-merges对于范围内的每个提交,检查主题是否符合以下正则:
<base>..HEAD^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([^)]+\))?!?: .+跳过已符合规范的提交。跳过合并提交(使用)。
git rev-list --no-mergesStep 4: Generate new messages
步骤4:生成新的提交消息
For each non-conformant commit:
- Inspect: and the diff body if needed
git show --stat <sha> - Pick a from the table above based on the change content
type - Pick an optional (module / file area) — omit if unsure
scope - Write a new subject: imperative mood, lowercase, ≤72 chars, no trailing period
- Preserve the original commit body verbatim. Only the subject line is rewritten. If the original body is empty, leave it empty.
See the "Mapping Common Non-Conformant Patterns" section below for typical translations.
对于每个不符合规范的提交:
- 检查:,必要时查看diff内容
git show --stat <sha> - 根据变更内容从上方的类型表中选择一个
type - 选择可选的(模块/文件区域)——不确定则省略
scope - 编写新主题:祈使语气、小写、≤72字符、无末尾句号
- 完整保留原始提交的正文内容。仅重写主题行。如果原始正文为空,则保持为空。
以下是常见不符合规范模式的映射参考,用于步骤4生成新主题。
Step 5: Show old → new plan
步骤5:展示旧→新提交计划
Rewrite plan: 3 commits
abc1234 added login feature
→ feat(auth): add login feature
def5678 Fixed bug
→ fix(api): handle null response in user fetch
ghi9012 WIP
→ chore: work-in-progress checkpointWait for explicit confirmation before applying.
重写计划:3个提交
abc1234 added login feature
→ feat(auth): add login feature
def5678 Fixed bug
→ fix(api): handle null response in user fetch
ghi9012 WIP
→ chore: work-in-progress checkpoint等待用户明确确认后再执行重写。
Step 6: Apply the rewrites (in-place)
步骤6:执行重写(就地)
Build the mapping file at . Each non-conformant commit gets one line:
/tmp/cc-rewrite-map.tsv<full-40-char-sha>\t<new full message including preserved body>The new full message is (or just if there is no body). Newlines inside the message are escaped as in the TSV; un-escapes them.
<new subject>\n\n<original body><new subject>\nrewrite_msg.pyThen run (use absolute path to the script):
bash
script="$HOME/.claude/skills/conventional-commit/scripts/rewrite_msg.py"在创建映射文件。每个不符合规范的提交对应一行:
/tmp/cc-rewrite-map.tsv<完整40位sha>\t<包含保留正文的完整新消息>完整新消息格式为(如果没有原始正文则仅为)。消息中的换行符在TSV中需转义为;会将其还原。
<新主题>\n\n<原始正文><新主题>\nrewrite_msg.py然后执行(使用脚本的绝对路径):
bash
script="$HOME/.claude/skills/conventional-commit/scripts/rewrite_msg.py"Plugin install path may differ; resolve via:
插件安装路径可能不同;可通过以下方式查找:
script=$(find ~/.claude -name rewrite_msg.py -path 'conventional-commit' | head -1)
script=$(find ~/.claude -name rewrite_msg.py -path 'conventional-commit' | head -1)
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f
--msg-filter "python3 '$script'"
"$base..HEAD"
--msg-filter "python3 '$script'"
"$base..HEAD"
The script reads `$GIT_COMMIT`, looks it up in `/tmp/cc-rewrite-map.tsv`, and prints the new message. Commits not in the map pass through unchanged.
**If `git filter-repo` is available** (preferred over `filter-branch`, which is deprecated): use it instead. But the bundled mapping flow currently relies on `filter-branch`; only switch if the user has `filter-repo` and prefers it.FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f
--msg-filter "python3 '$script'"
"$base..HEAD"
--msg-filter "python3 '$script'"
"$base..HEAD"
该脚本读取`$GIT_COMMIT`,在`/tmp/cc-rewrite-map.tsv`中查找并打印新消息。不在映射中的提交将保持不变。
**如果`git filter-repo`可用**(比已废弃的`filter-branch`更推荐):使用它替代。但当前的映射流程依赖`filter-branch`;仅当用户安装了`filter-repo`并偏好使用时才切换。Step 7: Branch-based rewrite (Option 3 from Step 2)
步骤7:基于分支的重写(步骤2中的选项3)
When commits are pushed and the user picks Option 3, do this instead of in-place rewrite:
bash
undefined当提交已推送到远程仓库且用户选择选项3时,执行以下操作而非就地重写:
bash
undefined1. Note current branch
1. 记录当前分支
src=$(git branch --show-current)
src=$(git branch --show-current)
2. Create a fresh branch off the upstream/base
2. 基于上游/基准创建新分支
git checkout -b "${src}-cc" "$base"
git checkout -b "${src}-cc" "$base"
3. Cherry-pick each commit, rewriting message as you go
3. 逐个复制提交并同时重写消息
for sha in $(git rev-list --reverse --no-merges "$base..$src"); do
new_msg=$(lookup_in_map "$sha") # from Step 4 plan; or compose interactively
git cherry-pick "$sha"
git commit --amend -m "$new_msg" # only the cherry-pick we just made
done
for sha in $(git rev-list --reverse --no-merges "$base..$src"); do
new_msg=$(lookup_in_map "$sha") # 来自步骤4的计划;或交互式编写
git cherry-pick "$sha"
git commit --amend -m "$new_msg" # 仅修改刚复制的提交
done
4. Verify, then push the new branch
4. 验证后推送新分支
git log --oneline "$base..HEAD"
git push -u origin "${src}-cc"
The original branch is untouched. The user can open a PR from `${src}-cc` and abandon the original branch when ready. **No force push, no destruction.**git log --oneline "$base..HEAD"
git push -u origin "${src}-cc"
原分支不受影响。用户可以从`${src}-cc`创建PR,准备就绪后废弃原分支。**无需强制推送,无破坏性操作。**Step 8: Post-rewrite cleanup
步骤8:重写后清理
After in-place rewrite (Step 6):
- Run and show the result.
git log --oneline "$base..HEAD" - Tell the user a backup ref was kept at and how to discard it once they're satisfied:
refs/original/refs/heads/<branch>Do not delete it automatically.bashgit update-ref -d refs/original/refs/heads/<branch> - Delete the temp file:
bash
rm -f /tmp/cc-rewrite-map.tsv
After branch-based rewrite (Step 7):
- Tell the user how to switch back if they change their mind:
bash
git checkout <original-branch> git branch -D <branch>-cc
就地重写(步骤6)后:
- 执行并展示结果。
git log --oneline "$base..HEAD" - 告知用户备份引用已保存至,以及确认无误后如何删除:
refs/original/refs/heads/<branch>不要自动删除。bashgit update-ref -d refs/original/refs/heads/<branch> - 删除临时文件:
bash
rm -f /tmp/cc-rewrite-map.tsv
基于分支的重写(步骤7)后:
- 告知用户如果改变主意如何切换回原分支:
bash
git checkout <original-branch> git branch -D <branch>-cc
Worked Example: messy history
示例流程:混乱的提交历史
User: 커밋 메시지 다시 써줘
(User shares git log:)
96b6be8 gnhf #43: Added User-Agent Parser ...
eda73c5 gnhf #42: Added JSON Schema Generator ...
e943794 gnhf #41: Added IPv4 Subnet Calculator ...
0a7e01e gnhf #40: Added Markdown TOC Generator ...
Step 1 (range):
upstream = origin/gnhf/prd-chann-tools-2026-8f2964
base = $(git merge-base HEAD origin/main)
Step 2 (safety):
✓ working tree clean
✓ HEAD attached
✗ all 4 commits exist on origin/<branch>
→ Show menu (Cancel / Force-push / New branch). User picks 3.
Step 3 (regex): all 4 fail the regex (start with "gnhf #N:")
Step 4 (mapping):
"gnhf #43: Added User-Agent Parser..." → feat(api-network): add user-agent parser
"gnhf #42: Added JSON Schema Generator" → feat(data-format): add JSON schema generator
"gnhf #41: Added IPv4 Subnet Calculator" → feat(api-network): add IPv4 subnet calculator
"gnhf #40: Added Markdown TOC Generator" → feat(text): add Markdown TOC generator
Drop the "gnhf #N" prefix (ticket-tracker noise; belongs in the body or a footer).
To preserve the ticket reference, add a footer:
Refs: gnhf#43
Step 5: show old → new plan, wait for confirmation.
Step 7 (branch-based):
git checkout -b feature-tools-cc origin/main
for sha in (cherry-pick each, --amend with new message)
git push -u origin feature-tools-cc用户:커밋 메시지 다시 써줘
(用户提供git log:)
96b6be8 gnhf #43: Added User-Agent Parser ...
eda73c5 gnhf #42: Added JSON Schema Generator ...
e943794 gnhf #41: Added IPv4 Subnet Calculator ...
0a7e01e gnhf #40: Added Markdown TOC Generator ...
步骤1(范围):
upstream = origin/gnhf/prd-chann-tools-2026-8f2964
base = $(git merge-base HEAD origin/main)
步骤2(安全检查):
✓ 工作区干净
✓ HEAD已关联分支
✗ 所有4个提交都已推送到origin/<branch>
→ 展示选项菜单(取消/强制推送/新分支)。用户选择3。
步骤3(正则检查):所有4个提交都不符合正则(以"gnhf #N:"开头)
步骤4(映射):
"gnhf #43: Added User-Agent Parser..." → feat(api-network): add user-agent parser
"gnhf #42: Added JSON Schema Generator" → feat(data-format): add JSON schema generator
"gnhf #41: Added IPv4 Subnet Calculator" → feat(api-network): add IPv4 subnet calculator
"gnhf #40: Added Markdown TOC Generator" → feat(text): add Markdown TOC generator
移除"gnhf #N"前缀(工单跟踪信息;应放在正文或页脚中)。
为保留工单关联,添加页脚:
Refs: gnhf#43
步骤5:展示旧→新计划,等待用户确认。
步骤7(基于分支):
git checkout -b feature-tools-cc origin/main
for sha in (逐个复制提交,使用--amend修改消息)
git push -u origin feature-tools-ccMapping Common Non-Conformant Patterns
常见不符合规范模式映射
Use these translations when generating new subjects in Step 4.
| Original pattern | Likely Conventional rewrite |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Skip (merge commits are excluded) |
| |
| |
| |
| |
| |
Rules of thumb:
- Past tense → imperative ("Added" → "add", "Fixed" → "fix")
- Capitalized → lowercase
- Strip trailing periods
- Ticket-tracker prefixes → move to a footer (don't drop the linkage)
Refs: - If the type is genuinely ambiguous between ,
chore, andrefactor, preferstylefor tooling/config,chorefor code-shape changes,refactoronly for whitespace/formattingstyle
在步骤4生成新主题时,可参考以下转换规则。
| 原始模式 | 对应的Conventional重写 |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 跳过(合并提交已被排除) |
| |
| |
| |
| |
| |
经验法则:
- 过去式→祈使语气("Added"→"add","Fixed"→"fix")
- 大写→小写
- 移除末尾句号
- 工单跟踪前缀→移至页脚(不要丢失关联)
Refs: - 如果类型在、
chore和refactor之间难以区分,工具/配置变更优先选style,代码结构变更优先选chore,仅空白字符/格式变更选refactorstyle
Quick Reference
快速参考
When stuck, ask:
| Symptom | Action |
|---|---|
| No working changes + messy history | Suggest |
| Working changes + messy history | Commit first, then |
| Pushed history + want to fix | Use Step 7 (branch-based rewrite) |
| Pre-commit hook fails | Fix the underlying issue; never |
| Push rejected (non-FF) | Stop, surface error, never |
| |
遇到问题时,请执行:
| 症状 | 操作 |
|---|---|
| 无工作区变更但提交历史混乱 | 建议使用 |
| 工作区有变更且提交历史混乱 | 先提交变更,再使用 |
| 提交已推送到远程仓库但需要修复 | 使用步骤7(基于分支的重写) |
| 预提交钩子失败 | 修复根本问题;绝不使用 |
| 推送被拒绝(非快进式) | 停止操作,显示错误,未经明确同意绝不使用 |
| 已设置 |
Common Mistakes
常见错误
Combining feat + fix in one commit
- Problem: mixes types
feat(auth): add OAuth and fix null response - Fix: Two separate commits, one feat one fix
Past-tense subjects
- Problem: "added login flow", "fixed bug"
- Fix: Imperative — "add login flow", "handle null response"
git add .- Problem: Accidentally stages secrets or unrelated changes
- Fix: Always per group
git add <explicit-paths>
Bypassing hooks with
--no-verify- Problem: Hides real issues; commit "works" locally but fails CI
- Fix: Investigate the hook failure; fix root cause; create fresh commit
Silently refusing rewrite of pushed history
- Problem: Says "I can't" with no path forward
- Fix: Present the 3-option menu in Step 2 (cancel / force-push / branch-based)
Dropping ticket references during rewrite
- Problem: "gnhf #43: Added X" → "feat: add X" loses the linkage
gnhf#43 - Fix: Move ticket to a footer; don't lose it
Refs: gnhf#43
Rewriting merge commits
- Problem: Filter-branch on merges scrambles parent linkage
- Fix: always
git rev-list --no-merges
将feat和fix合并到一个提交中
- 问题: 混合了不同类型
feat(auth): add OAuth and fix null response - 修复: 拆分为两个独立提交,一个feat一个fix
使用过去式主题
- 问题: "added login flow"、"fixed bug"
- 修复: 使用祈使语气——"add login flow"、"handle null response"
使用暂存所有内容
git add .- 问题: 意外暂存机密文件或无关变更
- 修复: 始终为每个分组使用
git add <明确路径>
使用绕过钩子
--no-verify- 问题: 隐藏真实问题;本地提交成功但CI失败
- 修复: 调查钩子失败原因;修复根本问题;创建新提交
直接拒绝重写已推送的提交历史
- 问题: 仅说"我不能"但不提供解决方案
- 修复: 展示步骤2中的三选项菜单(取消/强制推送/基于分支)
重写时丢失工单引用
- 问题: "gnhf #43: Added X"→"feat: add X"丢失了关联
gnhf#43 - 修复: 将工单信息移至页脚;不要丢失关联
Refs: gnhf#43
重写合并提交
- 问题: 在合并提交上使用filter-branch会打乱父提交关联
- 修复: 始终使用
git rev-list --no-merges
Red Flags
注意事项
Never:
- or
git add .(use explicit paths)git add -A - ,
--no-verify,--no-gpg-signwithout explicit user consent--amend - push (
--forceonly after explicit consent)--force-with-lease - Commit ,
.env*,credentials.*,*_rsa,*.pem,*.keywithout explicit user override*.p12 - Combine and
featin one commitfix - Rewrite pushed commits without showing the 3-option menu first
- Use
git filter-branch --root - Drop ticket references during rewrite (move them to footer)
Refs:
Always:
- Show a commit plan before creating commits
- Run after each commit to verify
git status --short - Preserve the original commit body verbatim during rewrite
- Use when listing commits to rewrite
--no-merges - Default to "Cancel" when prompting on pushed commits
- Match the repo's existing scope conventions (first)
git log -20 --oneline
绝不:
- 使用或
git add .(使用明确路径)git add -A - 未经用户明确同意使用、
--no-verify、--no-gpg-sign--amend - 使用推送(仅在用户明确同意后使用
--force)--force-with-lease - 未经用户明确覆盖提交、
.env*、credentials.*、*_rsa、*.pem、*.key*.p12 - 将和
feat合并到一个提交中fix - 未展示三选项菜单就重写已推送的提交
- 使用
git filter-branch --root - 重写时丢失工单引用(移至页脚)
Refs:
始终:
- 创建提交前展示提交计划
- 每次提交后运行验证
git status --short - 重写时完整保留原始提交的正文内容
- 列出要重写的提交时使用
--no-merges - 提示处理已推送提交时默认选择"取消"
- 匹配仓库现有的范围约定(先执行)
git log -20 --oneline
Behavior Notes
行为说明
Match the repo's existing style. Inspect first. If the repo uses Conventional Commits, mirror its scope conventions. If existing messages are mixed, default to lowercase descriptions and concise scopes.
git log -20 --onelineNarration vs. commit-message language. Conversation updates: user's prompt language. Commit messages: language already dominant in (English when ambiguous).
git logBe conservative with scopes. A scope must name a real module/area. If unsure, omit the scope rather than invent one.
Don't over-explain in bodies. A body should add context the subject can't carry (the why, a tricky tradeoff, related issue). If the subject is self-explanatory, no body.
Refuse, don't bypass. If a safety check fails (pushed commits without consent, dirty tree, detached HEAD, suspected secret), report and stop. Do not work around with destructive flags.
Trust explicit user override. "Force push", "yes I know it's pushed, rewrite anyway", "include the .env this time" → proceed, but state the risk in one line first.
匹配仓库现有风格。先执行检查。如果仓库使用Conventional Commits,遵循其范围约定。如果现有消息混合,默认使用小写描述和简洁范围。
git log -20 --oneline对话语言与提交消息语言。对话更新:使用用户提示的语言。提交消息:使用中占主导的语言(不确定时使用英文)。
git log范围使用要保守。范围必须指向真实的模块/区域。不确定时省略范围,不要凭空创造。
正文不要过度解释。正文应添加主题无法传达的上下文(原因、复杂的权衡、相关问题)。如果主题已能自解释,则无需正文。
拒绝而非绕过。如果安全检查失败(未经同意重写已推送提交、工作区不干净、HEAD分离、疑似机密文件),报告并停止操作。不要使用破坏性标志绕过。
尊重用户明确的覆盖要求。"Force push"、"yes I know it's pushed, rewrite anyway"、"include the .env this time"→执行操作,但先以一行文字说明风险。
Integration
集成
Pairs with:
- code-review — Run before committing as a final quality gate
/code-review - Any plugin commit hooks (commitlint, husky) — fix violations rather than
--no-verify
Called by: Manual user invocation only. Never auto-run during another skill's workflow.
搭配使用:
- code-review——提交前运行作为最终质量检查
/code-review - 任何插件提交钩子(commitlint、husky)——修复违规而非使用
--no-verify
调用方式: 仅由用户手动触发。绝不会在其他技能的工作流中自动运行。