Non-interactive, programmatic alternative to git add -p.
Every hunk gets a stable, content-based ID so you can inspect, filter, and stage changes without interactive prompts.
git add -p requires interactive input. That makes it unusable for:
- AI agents (Claude Code, Codex, etc.) that need to split changes into logical commits
- Scripts & CI/CD that automate commit organization
- Editor integrations that want hunk-level staging without shelling out to a TUI
git-hunk solves this by assigning each hunk a stable ID and exposing simple
stage/unstage/discard commands.
pip install git-hunkOr with uv:
uv tool install git-hunkVerify it works:
git-hunk --versionIf you use Claude Code, Codex, or similar AI agents:
npx skills add wkentaro/git-hunkOr copy SKILL.md to
~/.claude/skills/git-hunk/SKILL.md (or ~/.agents/...).
This installs a /git-hunk slash command that teaches the agent how to split
changes into logical commits.
# See all hunks across staged, unstaged, and untracked files
git-hunk list
# Show the diff for a specific hunk
git-hunk show d161935
# Stage specific hunks, then commit
git-hunk stage d161935 a3f82c1
git commit -m "feat: add validation for user input"
# Stage the remaining hunks
git-hunk stage e7b4012
git commit -m "fix: handle empty response in API client"git-hunk list # all hunks (unstaged + staged + untracked)
git-hunk list --unstaged # unstaged hunks only
git-hunk list --staged # staged hunks only
git-hunk list src/foo.py src/bar.py # specific files
git-hunk list --json # JSON output for scriptinggit-hunk show # show all hunks (staged + unstaged)
git-hunk show d161935 # show a single hunk
git-hunk show d161935 a3f82c1 # show multiple hunks
git-hunk show --staged # show all staged hunks
git-hunk show --unstaged # show all unstaged hunksgit-hunk stage d161935 # stage a hunk
git-hunk stage d161935 a3f82c1 # stage multiple hunks
git-hunk stage d161935 -l 3,5-7 # stage specific lines only
git-hunk unstage d161935 # move back to working tree
git-hunk unstage d161935 -l 3,5-7 # unstage specific lines only
git-hunk discard d161935 # restore from HEAD
git-hunk discard d161935 -l ^3,^5-7 # discard excluding specific linesgit-hunk list --json[
{
"id": "d161935",
"file": "src/main.py",
"status": "unstaged",
"header": "@@ -10,3 +10,5 @@",
"additions": 2,
"deletions": 0,
"diff": "..."
}
]| Interactive | Programmatic | Hunk IDs | Line-level control | JSON output | |
|---|---|---|---|---|---|
git add -p |
Yes | No | No | Yes | No |
git add <file> |
No | Yes | No | No | No |
git-hunk |
No | Yes | Yes | Yes | Yes |
- Parses
git diffoutput into individual hunks - Assigns each hunk a stable, content-based ID (SHA-256 prefix)
- For staging: reconstructs a minimal patch and pipes it through
git apply --cached - For discarding: reconstructs a reverse patch and applies it to the working tree
IDs are stable across partial staging -- they are derived from the changed lines,
not the @@ line numbers that shift as you stage hunks.
Bug reports, feature requests, and pull requests are welcome on GitHub.
git clone https://github.com/wkentaro/git-hunk.git
cd git-hunk
make setup # install dependencies
make test # run tests
make lint # run lintersMIT (LICENSE)
