| name | grim:dev:git-commit-decanter |
| description | (grim:dev:git-commit-decanter): (Git Commit Decanter): Use this for most commit planning, hunk staging, cleanup, and history-shaping git workflows. Do not auto-route simple read-only status/log/diff checks unless commit chunking or history surgery is actually in scope. |
Git Commit Decanter
Decant one monster diff into clean, settled chunks.
Grim workflow layer on top of git-surgeon: non-interactive hunk-level git operations for precise staging, splitting, and history shaping.
Upstream CLI: git-surgeon (currently tested against 0.1.17+).
Invocation Scope
Use this skill for most git workflows that involve:
- planning commits
- staging or splitting hunks
- cleaning up a dirty tree
- amending, folding, squashing, reordering, or otherwise shaping history
- preparing a reviewable commit stack
Do not invoke it for simple read-only git status, git log, git show, or git diff checks unless the user is asking about commit structure, cleanup, or history work.
Default Workflow (Plan First, Then Commit After Approval)
Default behavior when the user invokes this skill:
- inspect the current branch's uncommitted changes
- split them into a proposed stack of small, easily reviewable commits
- present a numbered commit list for user approval
- only execute the plan after the user approves it
Do not silently commit immediately after creating the plan unless the user explicitly pre-approves that behavior in the request.
Target commit count: default to between 3 and 20 commits.
- If the first pass produces fewer than 3 commits, look again for valid separations such as setup, behavior, refactor, tests, docs, tooling, or follow-up cleanup.
- Do not create fake or noisy commits just to hit the floor; if the diff is genuinely too small to support 3 meaningful commits, say so explicitly and use the smallest sensible number.
- If the first pass produces more than 20 commits, recombine adjacent micro-commits until each remaining commit still tells one clear story.
Workflow:
- Identify branch + working state:
git rev-parse --abbrev-ref HEAD
git status --porcelain
- List change hunks (IDs + previews):
git-surgeon hunks (unstaged)
git-surgeon hunks --staged (staged, if any)
- use
git-surgeon hunks --blame when deciding which earlier commit new lines belong with
- Create a numbered commit plan:
- Group hunks into small commits by intent (feature, fix, refactor, docs, tooling).
- Keep commits tight and reviewable. If one hunk mixes concerns, split it with
--lines.
- Aim for 3 to 20 commits overall unless the change set is truly smaller.
- Present the plan as a numbered list before committing.
- For each planned commit, include:
- proposed commit subject
- relevant files or hunk IDs
- brief reason this commit is separate
- Ask for approval:
- Ask the user to approve the numbered list before executing it.
- If the user requests changes, revise the numbered list and ask again.
- Ask for approval before merging, squashing, recombining, or otherwise changing planned commits into a different stack.
- Execute the approved plan:
- Use
git-surgeon commit <id...> -m "message" for each chunk.
- Repeat until
git-surgeon hunks is empty.
- If you need to adjust after the fact:
- Add missed hunks to an earlier commit: stage them and use
git-surgeon amend <commit>.
- Fold a finished commit into an earlier one:
git-surgeon fold <target> or git-surgeon fold <target> --from <commit>.
- If a commit is too large or mixed, use
git-surgeon split <sha> ... (see Split Workflow below).
- Reorder commits after splitting:
git-surgeon move <sha> --after <target>.
Chunking Rules (Make Review Easy)
- One concept per commit (avoid mixing refactor + behavior + docs unless the change is inseparable).
- Separate mechanical changes (renames/formatting) from behavioral changes.
- Keep tests with the code they validate, and use test-first sequencing when the user explicitly asks for it.
- Prefer smaller commits: if a diff hunk is a “bundle,” split it by line ranges.
- Default target is 3-20 commits for a meaningful working set; push upward when a larger diff contains multiple separable ideas.
- Build a narrative across commit messages: each commit should advance a clear story (
setup -> core behavior -> UX polish -> tests/docs) and the body should briefly explain why this step exists before the next one.
- Across all projects, never commit files under
output/ or tmp/ unless the user explicitly promotes them into the actual project. Do not hide those paths with .gitignore or .git/info/exclude; the visible git status signal is intentional.
Safety Rules
- Never push without explicit user request.
- Do not create the default commit stack until the user approves the numbered commit plan.
- Ask for approval before merging, squashing, recombining, or otherwise changing planned commits.
- Confirm before rewriting history on shared branches (especially
split, fold, amend, squash, move, or anything that implies force-push).
Commands
git-surgeon hunks
git-surgeon hunks --staged
git-surgeon hunks --file=src/main.rs
git-surgeon hunks --commit <HEAD/sha>
git-surgeon hunks --commit <sha> --full
git-surgeon hunks --blame
git-surgeon show <id>
git-surgeon show <id> --commit HEAD
git-surgeon stage <id1> <id2> ...
git-surgeon stage <id> --lines 5-30
git-surgeon commit <id1> <id2> ... -m "message"
git-surgeon commit <id>:1-11 <id2> -m "message"
git-surgeon commit-to <branch> <id1> <id2> ... -m "message"
git-surgeon unstage <id1> <id2> ...
git-surgeon unstage <id> --lines 5-30
git-surgeon discard <id1> <id2> ...
git-surgeon discard <id> --lines 5-30
git-surgeon amend <commit>
git-surgeon fold <target>
git-surgeon fold <target> --from <commit>
git-surgeon fold <target> --from <commit1> <commit2>
git-surgeon reword HEAD -m "new message"
git-surgeon reword <commit> -m "new message"
git-surgeon reword HEAD -m "subject" -m "body"
git-surgeon squash HEAD~2 -m
git-surgeon squash <commit> --force -m
git-surgeon undo <id1> <id2> ... --from <commit>
git-surgeon undo <> --from <commit> --lines 2-10
git-surgeon undo-file <file1> <file2> ... --from <commit>
git-surgeon move <sha> --after <target-sha>
git-surgeon move <sha> --before <target-sha>
git-surgeon move <sha> --to-end
git-surgeon HEAD \
--pick <id1> <id2> -m \
--rest-message
git-surgeon HEAD \
--pick <id1> -m -m \
--rest-message --rest-message
git-surgeon <commit> \
--pick <>:1-11,20-30 <id2> -m
git-surgeon HEAD \
--pick <id1> -m \
--pick <id2> -m \
--rest-message
git-surgeon update
Picking the Right Folding Command
| You have... | Use |
|---|
| Staged changes | git-surgeon amend <commit> |
| One existing commit, defaulting to HEAD | git-surgeon fold <target> |
| One or more named commits | git-surgeon fold <target> --from <commit...> |
Typical Workflow
git-surgeon hunks → list hunks with IDs
git-surgeon show <id> → inspect (lines numbered)
git-surgeon commit <id1> <id2> -m "message" (or stage separately → git commit)
- Partial hunk:
git-surgeon commit <id>:5-30 -m "message"
Amend Workflow
git-surgeon stage <id1> <id2>
git-surgeon amend <commit-sha> (HEAD → amend; older → autosquash rebase)
- Unstaged changes preserved
Undo Workflow
git-surgeon hunks --commit <sha>
git-surgeon undo <id> --from <sha> or git-surgeon undo-file src/main.rs --from <sha>
- Changes appear as unstaged modifications
Split Workflow
git-surgeon hunks --commit <sha> (use --full for line numbers)
git-surgeon split <sha> --pick <id1> -m "first" --rest-message "second"
- Multiple
-m flags → subject + body
id:range for partial hunks; commas for non-contiguous: --pick <id>:2-6,34-37
- HEAD → direct reset; older → rebase. Requires clean working tree.
Hunk IDs
- 7-char hex from file path + hunk content
- Stable while diff unchanged; duplicates get
-2, -3 suffixes
- ID not found → re-run
hunks for fresh IDs
Install
If git-surgeon is not installed, install from raine/git-surgeon:
brew install raine/git-surgeon/git-surgeon
Upgrade:
brew upgrade git-surgeon
git-surgeon update
Safety
- Commands like
discard, amend, fold, split, squash, and move can rewrite history or delete changes. Confirm with the user before rewriting history on shared branches or before force-pushing.