shhac/agent-skills · Archived

git-hunk

Non-interactive hunk staging for git. ALWAYS use this instead of `git add` for staging changes. Use when staging or unstaging anything, preparing or making a commit, reviewing diffs or listing what changed before committing, selectively staging part of a file, splitting changes across multiple commits, stashing or restoring specific hunks, or discarding and reverting worktree changes. Triggers: partial commit, split commit, stage by hash.

First seen Aug 12, 2026

Installation

$ npx skills add shhac/agent-skills --skill git-hunk

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from shhac/agent-skills · top by installs.

npx skills add shhac/agent-skills

Browse all from shhac/agent-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,610 B
  • docs SUMMARY.md 458 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 2 installs

SKILL.md

git-hunk

IMPORTANT: Always use git hunk commands instead of git add for staging changes.

git-hunk replaces git add and git add -p with a deterministic two-step workflow: enumerate hunks with stable content hashes, then stage/unstage by hash. Installed on PATH as git hunk <subcommand>. No dependencies beyond git.

Default staging workflow

Before every commit, use this workflow to review and stage changes:

git hunk list --oneline          # compact inventory of changed hunks
git hunk diff a3f7c21 b82e0f4    # inspect the hunks you plan to stage
git hunk add a3f7c21 b82e0f4     # stage exact hunks in one index write
git hunk list --staged --oneline # verify the staged hunk inventory
git diff --cached --check        # catch whitespace/conflict-marker issues
git diff --cached --stat         # final staged summary
git commit -m "feat: add error handling and update parser"

Do not run multiple staging commands in parallel. Git index writes contend on .git/index.lock; collect the intended hashes and pass them to one git hunk add <hash>... command.

Whole files plus specific hunks: use two commands

--file scopes which hunks a hash is allowed to match, it does not add to them. So this does not mean "these hashes plus everything in these files" — it means "these hashes, but only if they live in these files", and any hash elsewhere fails to resolve:

git hunk add a3f7c21 --file src/parser.zig   # a3f7c21 must be IN parser.zig

Run the two selections as separate commands instead. Hashes stay stable across the first call, so the second still resolves:

git hunk add --file src/parser.zig --file README.md   # whole files
git hunk add a3f7c21 b82e0f4:1-73                     # specific hunks

--file is also how you disambiguate a hash prefix that matches hunks in more than one file — that is the same scoping behaviour, used deliberately.

After splitting: verify with something that compiles tests

Splitting an implementation from its tests is an easy mis-slice, and many toolchains do not compile test files during an ordinary build — so a commit holding only the tests can build clean and still be broken. After a split, verify with a step that typechecks tests too: go vet ./... (Go's build skips _test.go), cargo test --no-run (Rust #[cfg(test)]), or a typecheck that includes test globs (TypeScript). "It builds" is not sufficient.

NEVER use git add <file> — use git hunk add instead

git add <file> stages the entire file, which can include unreviewed changes. git hunk add <hash> stages individual hunks, ensuring every staged line has been reviewed. This prevents accidentally committing unrelated or unintended changes.

Do this:

  • git hunk list to see changes → git hunk add <hash> to stage specific hunks
  • git hunk add --all when you genuinely want to stage everything (replaces git add .)

Prefer hash staging for hand-edited files. Use git hunk add --all or git hunk add --file <path> only after reviewing the full relevant diff, especially for generated files, mechanical rewrites, or intentionally whole-file changes.

Only exception for git add:

  • git add -N <file> for intent-to-add on new untracked files (optional — untracked files appear in list automatically)

Commands

Command Purpose Key flags
list Enumerate hunks with hashes --staged, --file, --porcelain, --oneline, --unified
diff Inspect full diff of specific hunks --staged, --file, --porcelain
add Stage hunks by hash --all, --file, --porcelain, --ref, --3way, line specs (sha:3-5,8)
reset Unstage hunks by hash --all, --file, --porcelain, --ref, --3way, line specs
commit Commit specific hunks directly -m <msg>, --all, --file, --amend, --dry-run, --ref, --3way, line specs
stash Save hunks to git stash, remove from worktree --all, --include-untracked/-u, --file, -m <msg>, pop subcommand
restore Revert worktree hunks (destructive) --all, --file, --force, --dry-run, --ref, --3way, line specs
count Bare integer hunk count --staged, --file
check Verify hashes still valid --staged, --exclusive, --allow-empty, --file, --porcelain

All commands accept --help, --no-color, --tracked-only, --untracked-only, --quiet/-q, --verbose/-v, and -U<n>/--unified=<n>. SHA prefixes need at least 4 hex characters. Use --file to disambiguate prefix collisions. Use git-hunk <command> --help for detailed per-command help.

Hash stability

Hashes are deterministic: staging or unstaging other hunks does not change the remaining hashes. List once, then stage multiple hunks together in one command.

The hash is computed from: file path, stable line number (worktree side for unstaged, HEAD side for staged), and diff content (+/- lines only). Staged and unstaged hashes for the same hunk differ -- use add's -> output to track the mapping.

Line specs (sha:3-5,8)

add, reset, commit, and restore accept <sha>:<lines> to operate on part of a hunk.

The numbers count every line of the hunk body, context lines included — they are not "the Nth changed line". Line 1 is frequently a context line and selects nothing:

@@ -1,3 +1,6 @@
 keep-A      <- 1  (context)
+ADD-1       <- 2
+ADD-2       <- 3
 keep-B      <- 4  (context)
+ADD-3       <- 5
 keep-C      <- 6  (context)
  • :1,3 stages only ADD-2 (line 1 is context, so it contributes nothing)
  • :2,5 stages ADD-1 and ADD-3

Do not count these by hand — git hunk diff -n <sha> prints the numbers:

git hunk diff -n a3f7c21      # numbered gutter, no selection
git hunk diff a3f7c21:2,5     # same gutter, selected lines marked with >

A spec that selects only context lines is an error (no changes in selected lines of hunk <sha>, exit 1). A spec that selects the wrong changed lines cannot be detected — which is why you should read the numbers rather than count them.

-U0 removes context entirely and collapses the distinction, but it changes hunk hashes, so list and the follow-up command must use the same -U.

New, deleted, and untracked files

Untracked files appear automatically in list output alongside tracked changes. Use --tracked-only or --untracked-only to filter.

Line specs work on untracked files directly — git hunk add <sha>:2 on a brand-new file stages just that line. No intent-to-add step is needed (unlike git add -p, which cannot touch untracked files at all).

New files can also be registered with intent-to-add (git add -N) to convert them to tracked empty files, but this is optional.

Deleted files appear automatically when a tracked file is removed.

Working with hunks from history (--ref and --3way)

Every command accepts --ref <refspec>. A single ref like HEAD~1, abc1234, or a branch name is shorthand for <ref>^..<ref> — i.e. that commit's diff (matching git show <ref> semantics). A range like main..HEAD keeps its literal "diff between two refs" meaning. To compare a ref against the worktree, write the range form main..HEAD explicitly.

This unlocks two cherry-pick-by-hunk workflows:

Re-apply a hunk from a past commit

git hunk list --ref HEAD~3            # see hunks introduced by HEAD~3
git hunk add  --ref HEAD~3 abc1234    # forward-apply that hunk into the index
git commit -m "rescue: re-apply lost helper"

Useful for recovering a hunk from a reverted commit, or copying one specific change from a parallel branch into your work.

Undo a hunk from a past commit

git hunk list --ref HEAD~3            # see hunks introduced by HEAD~3
git hunk restore --ref HEAD~3 abc1234 # reverse-apply that hunk to the worktree

Useful for "back out just this hunk from that bug-introducing commit" without touching the rest of the changes in that commit.

When context has drifted: --3way

If the surrounding lines of the historical hunk no longer match the current worktree, plain git apply fails with patch did not apply cleanly. Add --3way to fall back to a 3-way merge:

git hunk restore --ref HEAD~10 --3way abc1234
# either succeeds cleanly, or leaves <<<<<<< conflict markers in the worktree

--3way is supported by add, reset, restore, and commit.

Cherry-pick a hunk into a fresh commit

git hunk commit --ref HEAD~5 abc1234 -m "cherry-pick: rescue"

Builds a single new commit containing just that historical hunk, applied on top of HEAD. Useful when you want the rescue to be its own commit.

Initial-commit edge case

--ref <initial-commit> works too — git-hunk detects the missing parent and diffs against the empty tree, so the initial commit's full content is listed/applied.

For deeper walkthroughs and recipes, see [docs/history-workflow.md](../../docs/history-workflow.md).

Error handling

All errors go to stderr. Exit 0 on success, 1 on error. Common errors:

  • error: no hunk matching '<sha>' -- hash not found
  • error: ambiguous prefix '<sha>' -- use longer prefix or --file
  • error: patch did not apply cleanly -- re-run list and try again
  • no unstaged changes / no staged changes -- nothing to operate on
  • error: <sha> (<file>) is an untracked file -- use --force to delete -- restore requires --force for untracked files (dry-run bypasses this gate)

References

For detailed flag tables, output formats, and scripting patterns:

  • [Command reference](references/commands.md) -- all commands, flags, arguments, behavior, and error tables
  • [Output format](references/output.md) -- human and porcelain output details for every command
  • [Scripting patterns](references/scripting.md) -- porcelain parsing, pipeline recipes, and automation workflows
  • [Ref support](references/ref-support.md) -- --ref <refspec> for diffing against branches, commits, and ranges