git-staging
Original:🇺🇸 English
Translated
Stage files, hunks, or specific lines in git non-interactively.
6installs
Sourceaspiers/ai-config
Added on
NPX Install
npx skill4agent add aspiers/ai-config git-stagingTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Non-interactive Git Staging
When to use this skill
Use this skill when you need to:
- Stage only specific hunks from a file (not the entire file)
- Stage only specific lines within a hunk
- Avoid interactive git commands (,
git add -p, etc.)git add -i - Programmatically control exactly what gets staged
Step 1: Assess the changes
Before choosing a staging method, determine what changes exist:
bash
git status # See which files have changes
git diff --no-ext-diff # See all unstaged changes
git diff --cached --no-ext-diff # See already-staged changesDecision tree:
- If only ONE file has changes and you want ALL of them staged → use
git add <file> - If ONE file has multiple unrelated hunks and you want only SOME → use Method 2 or 3
- If MULTIPLE files need staging → stage per-file with for each, or selectively with patch method
git add
Why not use git add -p
?
git add -pInteractive git commands require a TTY and human input. AI agents cannot
reliably fake interactive sessions - attempts using or are
fragile and often fail. Instead, construct patches programmatically and apply
them directly to the index.
echo "y"yesCore technique
The key insight is that applies a patch directly to the
staging area (index) without modifying the working tree. This lets you stage
precise changes non-interactively.
git apply --cachedTemporary files
All temporary patch files should be written to within the repository
(not ) to avoid permission prompts. Ensure the directory exists first:
tmp//tmpbash
mkdir -p tmpMethods
Method 1: Stage entire file
When you want to stage all changes in a file:
bash
git add <file>Method 2: Stage specific hunks via patch
When you need to stage only certain hunks from a file:
-
Generate the full diff for the file:bash
git diff <file> > tmp/full.patch -
Edit the patch to keep only the hunks you want to stage (use the Edit tool or create a new file with only the desired hunks)
-
Apply the edited patch to the index:bash
git apply --cached tmp/selected.patch
Method 3: Stage specific lines within a hunk
When you need to stage only certain lines within a hunk, you must carefully
edit the patch to maintain validity:
-
Generate the diff:bash
git diff <file> > tmp/full.patch -
Edit the patch, following these rules for the hunk you're modifying:
- Keep the hunk header but adjust the line counts
@@ - To exclude an added line (): remove the entire line from the patch
+ - To exclude a removed line (): change
-to a space (-) to make it context - Adjust the line counts in the header to match
@@ -X,Y +X,Z @@
- Keep the
-
Apply:bash
git apply --cached tmp/selected.patch
Patch format reference
A unified diff patch has this structure:
diff
diff --git a/file.txt b/file.txt
index abc123..def456 100644
--- a/file.txt
+++ b/file.txt
@@ -10,6 +10,8 @@ optional context label
context line (unchanged)
-removed line
+added line
context line (unchanged)Hunk header format
@@ -START,COUNT +START,COUNT @@- First pair: original file (lines being removed or used as context)
- Second pair: new file (lines being added or used as context)
- COUNT = number of lines in that side of the hunk (context + changes)
Line prefixes
- (space): context line (unchanged, appears in both versions)
- : line only in original (will be removed)
- - : line only in new version (will be added)
+
Example: Staging only the second hunk
Given a file with two hunks of changes:
bash
# Generate full diff
git diff --no-ext-diff myfile.py > tmp/full.patchThe patch might look like:
diff
diff --git a/myfile.py b/myfile.py
index abc123..def456 100644
--- a/myfile.py
+++ b/myfile.py
@@ -5,6 +5,7 @@ import os
def foo():
pass
+ # Added comment in first hunk
def bar():
@@ -20,6 +21,7 @@ def bar():
def baz():
pass
+ # Added comment in second hunkTo stage only the second hunk, create a new patch with just that hunk:
diff
diff --git a/myfile.py b/myfile.py
index abc123..def456 100644
--- a/myfile.py
+++ b/myfile.py
@@ -20,6 +21,7 @@ def bar():
def baz():
pass
+ # Added comment in second hunkThen apply:
bash
git apply --cached tmp/second-hunk.patchExample: Excluding specific added lines
If you have a hunk with multiple additions but only want to stage some:
Original hunk:
diff
@@ -10,4 +10,7 @@
existing line
+line I want to stage
+line I do NOT want to stage
+another line I want to stage
more contextEdit to exclude the unwanted line (remove it entirely and adjust count):
diff
@@ -10,4 +10,6 @@
existing line
+line I want to stage
+another line I want to stage
more contextNote: The became because we removed one added line.
+10,7+10,6Verification
After applying, verify what was staged:
bash
git diff --cached # Show staged changes
git diff # Show unstaged changes (should include excluded hunks)
git status # Overview of staged/unstaged stateCommon pitfalls
-
Invalid line counts: If theheader counts don't match the actual lines in the hunk,
@@will fail. Always recount after editing.git apply -
Missing newline at EOF: Patches are sensitive to trailing newlines. Watch formarkers.
\ No newline at end of file -
Whitespace corruption: Ensure context lines start with a space, not an empty prefix. Some editors strip trailing spaces.
-
Index mismatch: Theline is optional for
index abc123..def456. If you have issues, try removing it.git apply --cached
Troubleshooting
If fails:
git apply --cached-
Test the patch first without:
--cachedbashgit apply --check tmp/selected.patch -
Use verbose mode to see what's happening:bash
git apply --cached -v tmp/selected.patch -
Common error messages:
- "patch does not apply": Line counts are wrong or context doesn't match
- "patch fragment without header": Missing the or
diff --gitlines---/+++