SKILL.md
Skill: Commit Rewriter
Rewrite commit messages in three phases: prepare, draft, apply. Follows .github/git-commit-instructions.md.
Scripts
Reusable scripts live in scripts/ relative to this SKILL.md:
| Script | Purpose |
|---|---|
scripts/buildrebasetodo.py |
Parses commitrewritemapping.md + git log, writes /tmp/rebasetodo.txt and /tmp/commitmsg_mapping.json. |
scripts/msg_filter.py |
Reads /tmp/commitmsgmapping.json; used as git filter-branch --msg-filter. |
scripts/verify.sh |
Checks commit count and diffs against BACKUP branch. |
Process Overview
Phase 1 — Preparation
- Verify
<branch>-BACKUPexists; refuse to proceed if missing. - Detect branch point (
merge-baseor user-provided). - List commits; locate plan file (e.g.,
plan-*.md) or ask. - Report findings, wait for confirmation
→ Phase 2 — Analysis & Message Drafting.
Phase 2 — Analysis & Message Drafting
- Analyze
git --no-pager diff --statper commit. - Read the plan as context — diff stats take priority.
Describe what actually changed, not what the plan intended.
- Map commits to plan steps (by file overlap and intent):
- At most one actual commit per plan step; unmapped is fine. - Mapped → title starts with Step X:. Unmapped → plain title.
- Generate new messages per
.github/git-commit-instructions.md. - Write
commitrewritemapping.mdin the project root:
| # | Old message | New message | Plan step | Comments |
|---|---|---|---|---|
| 1 | feat: add X |
Step 1: Add X to Y |
Step 1 | — |
| 2 | fix typo |
Fix typo in Z |
— | merge with #1 |
| 3 | wip |
— | — | delete — empty commit |
Comments column: suggest merge/squash/delete where appropriate.
- Report table, wait for confirmation
→ Phase 3 — Rewrite & Verify. User may edit the file before confirming; Phase 3 re-reads it and treats every change as authoritative (renamed titles, accepted/rejected merges, reassigned mappings).
Phase 3 — Rewrite & Verify
All commands below use SCRIPTS=.github/skills/pavlo-commit-rewriter/scripts.
- Stash uncommitted changes (rebase and filter-branch require a clean tree):
`` git stash ``
- Generate rebase todo and message mapping:
`` python3 -u $SCRIPTS/buildrebasetodo.py \ --mapping commitrewritemapping.md \ --branch-point <hash> ` This writes /tmp/rebasetodo.txt and /tmp/commitmsg_mapping.json`. Review the printed summary (pick/fixup/drop counts).
- Rebase (only if fixup or drop rows exist):
`` GITSEQUENCEEDITOR="cp /tmp/rebase_todo.txt" \ git rebase -i <branch-point> `` Commit count decreases after rebase; the build script prints the expected count.
- Rewrite messages:
`` cp $SCRIPTS/msgfilter.py /tmp/msgfilter.py FILTERBRANCHSQUELCHWARNING=1 \ git filter-branch -f --msg-filter \ 'python3 /tmp/msgfilter.py /tmp/commitmsgmapping.json' \ <branch-point>..HEAD ``
- Verify:
`` bash $SCRIPTS/verify.sh <branch-point> <branch> <expected-count> `` - Checks commit count matches expected. - Lists all rewritten messages. - Diffs against BACKUP; warns if non-empty.
- Restore stashed changes:
`` git stash pop ``
Rules
- No git pager. Every git command must use
git --no-pager.
Bare git log / git diff blocks the agent.
- Match by subject line, not hash (hashes change after rewrite/rebase).
- Commit count changes after rebase. Verify the new count
(printed by buildrebasetodo.py) before running filter-branch.
- Named phases. Always name the next phase when asking for confirmation.
- User edits are authoritative. Phase 3 honours all changes
the user made to commitrewritemapping.md.
- Stash before rewrite. Phase 3 operations require a clean working tree.
Stash before starting, pop after verification.
Related
.github/git-commit-instructions.md— commit message conventions.pavlo-commit-by-commit-execution— execution skill usingStep X:naming.