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
# List hunks
git-surgeon hunks # unstaged (ID, file, +/- counts, preview)
git-surgeon hunks --staged # staged
git-surgeon hunks --file=src/main.rs # filter by file
git-surgeon hunks --commit <HEAD/sha> # from specific commit
git-surgeon hunks --commit <sha> --full # with line numbers (for line-range splits)
git-surgeon hunks --blame # show introducing commit per line
# Show full diff for hunk (lines numbered for --lines)
git-surgeon show <id>
git-surgeon show <id> --commit HEAD
# Stage
git-surgeon stage <id1> <id2> ...
git-surgeon stage <id> --lines 5-30
# Stage + commit in one step
git-surgeon commit <id1> <id2> ... -m "message"
git-surgeon commit <id>:1-11 <id2> -m "message" # inline line ranges
# Commit hunks directly to another branch (no checkout)
git-surgeon commit-to <branch> <id1> <id2> ... -m "message"
# Unstage
git-surgeon unstage <id1> <id2> ...
git-surgeon unstage <id> --lines 5-30
# Discard working tree changes
git-surgeon discard <id1> <id2> ...
git-surgeon discard <id> --lines 5-30
# Fold staged changes into an earlier commit
git-surgeon amend <commit>
# Fold existing commit(s) into an earlier commit
git-surgeon fold <target>
git-surgeon fold <target> --from <commit>
git-surgeon fold <target> --from <commit1> <commit2>
# Reword commit message
git-surgeon reword HEAD -m "new message"
git-surgeon reword <commit> -m "new message"
git-surgeon reword HEAD -m "subject" -m "body"
# Squash commits from target through HEAD into one
git-surgeon squash HEAD~2 -m "combined feature"
git-surgeon squash <commit> --force -m "squash with merges"
# Undo hunks from commit (reverse-apply → working tree)
git-surgeon undo <id1> <id2> ... --from <commit>
git-surgeon undo <id> --from <commit> --lines 2-10
# Undo entire files from commit
git-surgeon undo-file <file1> <file2> ... --from <commit>
# Reorder commits
git-surgeon move <sha> --after <target-sha>
git-surgeon move <sha> --before <target-sha>
git-surgeon move <sha> --to-end
# Split commit by hunk selection
git-surgeon split HEAD \
--pick <id1> <id2> -m "first commit" \
--rest-message "remaining changes"
# Split with subject + body
git-surgeon split HEAD \
--pick <id1> -m "Add feature" -m "Detailed description." \
--rest-message "Other changes" --rest-message "Body for rest."
# Split with line ranges (comma for non-contiguous)
git-surgeon split <commit> \
--pick <id>:1-11,20-30 <id2> -m "partial split"
# Split into 3+ commits
git-surgeon split HEAD \
--pick <id1> -m "first" \
--pick <id2> -m "second" \
--rest-message "rest"
# Upgrade git-surgeon itself
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
# or
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.
1---2name: grim-dev-git-commit-decanter3description: (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.4---5# Git Commit Decanter67Decant one monster diff into clean, settled chunks.89Grim workflow layer on top of [git-surgeon](https://github.com/raine/git-surgeon): non-interactive hunk-level git operations for precise staging, splitting, and history shaping.1011Upstream CLI: `git-surgeon` (currently tested against `0.1.17+`).1213## Invocation Scope1415Use this skill for most git workflows that involve:16- planning commits17- staging or splitting hunks18- cleaning up a dirty tree19- amending, folding, squashing, reordering, or otherwise shaping history20- preparing a reviewable commit stack2122Do 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.2324## Default Workflow (Plan First, Then Commit After Approval)2526Default behavior when the user invokes this skill:27- inspect the current branch's uncommitted changes28- split them into a proposed stack of small, easily reviewable commits29- present a numbered commit list for user approval30- only execute the plan after the user approves it3132Do not silently commit immediately after creating the plan unless the user explicitly pre-approves that behavior in the request.3334Target commit count: default to between 3 and 20 commits.3536- 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.37- 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.38- If the first pass produces more than 20 commits, recombine adjacent micro-commits until each remaining commit still tells one clear story.3940Workflow:41421. Identify branch + working state:43 - `git rev-parse --abbrev-ref HEAD`44 - `git status --porcelain`452. List change hunks (IDs + previews):46 - `git-surgeon hunks` (unstaged)47 - `git-surgeon hunks --staged` (staged, if any)48 - use `git-surgeon hunks --blame` when deciding which earlier commit new lines belong with493. Create a numbered commit plan:50 - Group hunks into small commits by intent (feature, fix, refactor, docs, tooling).51 - Keep commits tight and reviewable. If one hunk mixes concerns, split it with `--lines`.52 - Aim for 3 to 20 commits overall unless the change set is truly smaller.53 - Present the plan as a numbered list before committing.54 - For each planned commit, include:55 - proposed commit subject56 - relevant files or hunk IDs57 - brief reason this commit is separate584. Ask for approval:59 - Ask the user to approve the numbered list before executing it.60 - If the user requests changes, revise the numbered list and ask again.61 - Ask for approval before merging, squashing, recombining, or otherwise changing planned commits into a different stack.625. Execute the approved plan:63 - Use `git-surgeon commit <id...> -m "message"` for each chunk.64 - Repeat until `git-surgeon hunks` is empty.656. If you need to adjust after the fact:66 - Add missed hunks to an earlier commit: stage them and use `git-surgeon amend <commit>`.67 - Fold a finished commit into an earlier one: `git-surgeon fold <target>` or `git-surgeon fold <target> --from <commit>`.68 - If a commit is too large or mixed, use `git-surgeon split <sha> ...` (see Split Workflow below).69 - Reorder commits after splitting: `git-surgeon move <sha> --after <target>`.7071### Chunking Rules (Make Review Easy)72- One concept per commit (avoid mixing refactor + behavior + docs unless the change is inseparable).73- Separate mechanical changes (renames/formatting) from behavioral changes.74- Keep tests with the code they validate, and use test-first sequencing when the user explicitly asks for it.75- Prefer smaller commits: if a diff hunk is a “bundle,” split it by line ranges.76- Default target is 3-20 commits for a meaningful working set; push upward when a larger diff contains multiple separable ideas.77- 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.78- 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.7980### Safety Rules81- Never push without explicit user request.82- Do not create the default commit stack until the user approves the numbered commit plan.83- Ask for approval before merging, squashing, recombining, or otherwise changing planned commits.84- Confirm before rewriting history on shared branches (especially `split`, `fold`, `amend`, `squash`, `move`, or anything that implies force-push).8586## Commands8788```bash89# List hunks90git-surgeon hunks # unstaged (ID, file, +/- counts, preview)91git-surgeon hunks --staged # staged92git-surgeon hunks --file=src/main.rs # filter by file93git-surgeon hunks --commit <HEAD/sha> # from specific commit94git-surgeon hunks --commit <sha> --full # with line numbers (for line-range splits)95git-surgeon hunks --blame # show introducing commit per line9697# Show full diff for hunk (lines numbered for --lines)98git-surgeon show <id>99git-surgeon show <id> --commit HEAD100101# Stage102git-surgeon stage <id1> <id2> ...103git-surgeon stage <id> --lines 5-30104105# Stage + commit in one step106git-surgeon commit <id1> <id2> ... -m "message"107git-surgeon commit <id>:1-11 <id2> -m "message" # inline line ranges108109# Commit hunks directly to another branch (no checkout)110git-surgeon commit-to <branch> <id1> <id2> ... -m "message"111112# Unstage113git-surgeon unstage <id1> <id2> ...114git-surgeon unstage <id> --lines 5-30115116# Discard working tree changes117git-surgeon discard <id1> <id2> ...118git-surgeon discard <id> --lines 5-30119120# Fold staged changes into an earlier commit121git-surgeon amend <commit>122123# Fold existing commit(s) into an earlier commit124git-surgeon fold <target>125git-surgeon fold <target> --from <commit>126git-surgeon fold <target> --from <commit1> <commit2>127128# Reword commit message129git-surgeon reword HEAD -m "new message"130git-surgeon reword <commit> -m "new message"131git-surgeon reword HEAD -m "subject" -m "body"132133# Squash commits from target through HEAD into one134git-surgeon squash HEAD~2 -m "combined feature"135git-surgeon squash <commit> --force -m "squash with merges"136137# Undo hunks from commit (reverse-apply → working tree)138git-surgeon undo <id1> <id2> ... --from <commit>139git-surgeon undo <id> --from <commit> --lines 2-10140141# Undo entire files from commit142git-surgeon undo-file <file1> <file2> ... --from <commit>143144# Reorder commits145git-surgeon move <sha> --after <target-sha>146git-surgeon move <sha> --before <target-sha>147git-surgeon move <sha> --to-end148149# Split commit by hunk selection150git-surgeon split HEAD \151 --pick <id1> <id2> -m "first commit" \152 --rest-message "remaining changes"153154# Split with subject + body155git-surgeon split HEAD \156 --pick <id1> -m "Add feature" -m "Detailed description." \157 --rest-message "Other changes" --rest-message "Body for rest."158159# Split with line ranges (comma for non-contiguous)160git-surgeon split <commit> \161 --pick <id>:1-11,20-30 <id2> -m "partial split"162163# Split into 3+ commits164git-surgeon split HEAD \165 --pick <id1> -m "first" \166 --pick <id2> -m "second" \167 --rest-message "rest"168169# Upgrade git-surgeon itself170git-surgeon update171```172173## Picking the Right Folding Command174175| You have... | Use |176| --- | --- |177| Staged changes | `git-surgeon amend <commit>` |178| One existing commit, defaulting to HEAD | `git-surgeon fold <target>` |179| One or more named commits | `git-surgeon fold <target> --from <commit...>` |180181## Typical Workflow1821831. `git-surgeon hunks` → list hunks with IDs1842. `git-surgeon show <id>` → inspect (lines numbered)1853. `git-surgeon commit <id1> <id2> -m "message"` (or stage separately → `git commit`)1864. Partial hunk: `git-surgeon commit <id>:5-30 -m "message"`187188## Amend Workflow1891901. `git-surgeon stage <id1> <id2>`1912. `git-surgeon amend <commit-sha>` (HEAD → amend; older → autosquash rebase)1923. Unstaged changes preserved193194## Undo Workflow1951961. `git-surgeon hunks --commit <sha>`1972. `git-surgeon undo <id> --from <sha>` or `git-surgeon undo-file src/main.rs --from <sha>`1983. Changes appear as unstaged modifications199200## Split Workflow2012021. `git-surgeon hunks --commit <sha>` (use `--full` for line numbers)2032. `git-surgeon split <sha> --pick <id1> -m "first" --rest-message "second"`2043. Multiple `-m` flags → subject + body2054. `id:range` for partial hunks; commas for non-contiguous: `--pick <id>:2-6,34-37`2065. HEAD → direct reset; older → rebase. Requires clean working tree.207208## Hunk IDs209210- 7-char hex from file path + hunk content211- Stable while diff unchanged; duplicates get `-2`, `-3` suffixes212- ID not found → re-run `hunks` for fresh IDs213214## Install215216If `git-surgeon` is not installed, install from [raine/git-surgeon](https://github.com/raine/git-surgeon):217218```bash219brew install raine/git-surgeon/git-surgeon220```221222Upgrade:223224```bash225brew upgrade git-surgeon226# or227git-surgeon update228```229230## Safety231232- 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.