| name | hunk |
| description | Line-level git staging and non-interactive rebase for agents that know exactly which lines they changed. Use when you need atomic commits carved out of a larger diff, or when you need to squash/drop/reorder/reword commits without interactive prompts. |
Hunk
Hunk gives line-level git staging and non-interactive rebase, built for AI agents rather than a human at a terminal.
Precision staging
Use hunk instead of plain git add when:
- You modified multiple areas of a file but only want to commit some of the changes.
- You want atomic, focused commits carved out of a larger set of changes.
- You need to stage specific line ranges without interactive prompts.
Core workflow:
hunk diff --json
hunk diff
hunk stage main.go:42-45
hunk stage main.go:10-20,30-40
hunk preview
hunk commit -m "message"
hunk reset
FILE:LINES syntax:
file.go:10 - Single line
file.go:10-20 - Range (inclusive)
file.go:10-20,30-40 - Multiple ranges in one file
file.go:10 other.go:5-8 - Multiple files (space-separated)
Line numbers refer to new file lines (what editors display), not old file lines.
Atomic change groups: when a replacement (deletions + additions with no context between them) is partially selected, hunk automatically includes the entire group. You cannot stage half a replacement, the deletions and additions are atomic. Pure-addition and pure-deletion groups can still be individually line-selected.
Fallback when staging fails: if hunk stage fails with "patch does not apply," fall back to git add <file> for whole-file staging, broader line ranges that cover entire change groups, or stage file-by-file instead of cherry-picking lines across many hunks.
Best practices: run hunk diff --json to get exact line numbers before staging. Use hunk preview to verify the patch looks correct before committing. For focused commits, stage only related changes together.
Programmatic rebase
Use hunk's rebase commands when you need to squash fixup commits into their parent, drop debug/temporary commits before a PR, reorder commits for logical grouping, or run commands (tests) between commits during a rebase.
Core workflow:
hunk rebase list --onto main
hunk rebase run --onto main <actions>
hunk rebase status
hunk rebase continue
hunk rebase abort
Action syntax (comma-separated):
pick:abc123 - Keep commit as-is
squash:abc123 - Combine with previous (concat messages)
fixup:abc123 - Combine with previous (discard message)
drop:abc123 - Remove commit from history
reword:abc123:New message - Change commit message
exec:make test - Run command after previous commit
Common patterns:
hunk rebase list --onto main --json
hunk rebase run --onto main "pick:abc123,squash:def456"
hunk rebase run --onto main "pick:abc123,drop:debug1,pick:ghi789"
hunk rebase run --onto main "pick:abc123,exec:go test ./...,pick:def456,exec:go test ./..."
hunk rebase run --onto main "pick:abc123,reword:def456:fix: correct nil check in handshake"
hunk rebase run --onto main "pick:feat1,fixup:typo1,pick:feat2,fixup:typo2"
Auto-squash (preferred for fixup commits):
hunk rebase autosquash --onto main
hunk rebase autosquash --onto main --dry-run
Create fixups with git commit --fixup=<sha>, then auto-squash.
Conflict handling:
hunk rebase status
git add <resolved-files>
hunk rebase continue
hunk rebase abort
Best practices: always run hunk rebase list --onto <base> --json first to get exact hashes. Prefer autosquash over manual run when squashing fixups. Use fixup (not squash) when you want to silently fold in typo fixes. Run hunk rebase status after a run to verify completion.