git-surgeon
Surgical, non-interactive git hunk control for AI agents. Think git add -p for
agents.
Without hunk-level staging, an AI agent that needs to commit two independent changes in the same file has to edit one change out, commit, then restore it. git-surgeon lets the agent stage each hunk separately — no gymnastics.
Installation
Cargo
Requires Rust. Install via rustup if you don't have it.
Quick start
# List all unstaged hunks with IDs and previews
# Stage specific hunks
# Commit as usual
Commands
hunks— List hunks in the diffshow— Show full diff for a specific hunkstage— Stage hunks by IDunstage— Unstage hunks by IDdiscard— Discard working tree changes for hunksfixup— Fold staged changes into an earlier commitundo— Reverse-apply hunks from a commit
hunks
Lists all hunks with their IDs, file paths, function context, change counts, and a preview of changed lines.
# List unstaged hunks
# List staged hunks
# Filter to a specific file
# List hunks from a specific commit
Example output
a1b2c3d src/main.rs fn handle_request (+3 -1)
- let result = process(input);
+ let result = match process(input) {
+ Ok(v) => v,
+ Err(e) => return Err(e),
+ };
e4f5678 src/lib.rs (+1 -0)
+use std::collections::HashMap;
Each line shows: <hunk-id> <file> [function context] (+additions -deletions)
show
Shows the full diff (header + all lines) for a single hunk.
# Show a hunk from a specific commit
Searches both unstaged and staged diffs when no --commit is specified.
stage
Stages one or more hunks by ID. Equivalent to selectively answering "y" in
git add -p.
unstage
Unstages one or more previously staged hunks, moving them back to the working tree.
discard
Discards working tree changes for specific hunks. This reverse-applies the
hunks, effectively running git checkout -p non-interactively.
Warning: This permanently removes uncommitted changes for the specified hunks.
fixup
Folds currently staged changes into an earlier commit. Uses git commit --amend
for HEAD, or an autosquash rebase for older commits. Unstaged changes are
preserved via --autostash.
# Stage some hunks, then fixup an earlier commit
# Fixup HEAD (equivalent to git commit --amend --no-edit)
If the rebase hits a conflict, the repo is left in the conflict state for manual
resolution (git rebase --continue or git rebase --abort).
undo
Reverse-applies hunks from a specific commit onto the working tree. Useful for selectively reverting parts of a previous commit without reverting the entire commit.
# List hunks from the commit to find IDs
# Undo specific hunks
The changes appear as unstaged modifications in the working tree. Fails gracefully if context lines have changed since the commit (the patch no longer applies cleanly).
How hunk IDs work
IDs are 7-character hex strings derived from SHA-1 of the file path and hunk
content (the actual +/-/context lines, excluding the @@ header). This
means:
- IDs are stable across line shifts — adding lines above a hunk doesn't change its ID
- IDs are deterministic — the same content always produces the same ID
- Collisions get a
-2,-3suffix (e.g.,a1b2c3d-2)
Typical AI agent workflow
# 1. Agent makes changes to multiple files
# 2. Review what changed
# 3. Stage only the hunks related to feature A
# 4. Commit feature A
# 5. Stage remaining hunks for feature B
Requirements
- Git 2.0+
- Rust (for building from source)