Fine-grained Git staging and deterministic draft-history refinement
Writing code is messy. Git history doesn't have to be.
During development we experiment, refactor, backtrack, and fix mistakes. If every step ends up as a commit, the history becomes noise. A curated history turns that process into a clear sequence of logical changes.
git-stage-batch combines fine-grained staging of uncommitted changes with
deterministic refinement of clean, linear draft commits. Use hunks, lines, and
batches to shape new commits around meaning, or use a validated semantic plan
to reword or split commits, integrate later repairs, and reorder
proven-independent changes in an existing local draft series while preserving
its final Git tree. Rewriting is limited to unpublished history by default; a
verified force-push review-head exception permits only the local rewrite and
neither performs nor authorizes a push.
- Command-based workflow - Perfect for automation and AI coding assistants
- Line-level control - Stage specific lines within a hunk for maximum granularity
- Interactive mode - Menu-driven hunk-by-hunk workflow inspired by
git add -p - State persistence - Resume staging across multiple invocations
- Batch operations - Save hunks for later, organize complex changes
- Deterministic history refinement - Validate and execute semantic rewrites of local draft commits
- Machine-readable output -
--porcelainflag for scripting - No runtime Python packages - Uses the standard library and the external Git executable
# Start reviewing hunks
git-stage-batch start
# Include the selected hunk (stage it)
git-stage-batch include
# Skip it for now
git-stage-batch skip
# Discard it (remove from working tree)
git-stage-batch discard
# Stage specific lines within a hunk
git-stage-batch include --line 1,3,5-7
git-stage-batch skip --line 2,4
git-stage-batch discard --line 8-10
# Check what's been processed
git-stage-batch status
# Start fresh after committing
git-stage-batch again# Install the command
python -m pipx install git-stage-batch
# Install Claude Code commit skills into this repository
git-stage-batch install-assets claude-skills --filter 'commit-*'
# Keep the local Claude assets out of reviews
git-stage-batch block-file --local-only .claude/
# Ask Claude Code to split and commit the unstaged work
claude "/commit-unstaged-changes"Omit --filter when installing Claude skills if you also want the larger
/decompose-and-commit-unstaged-changes workflow and the standalone
/refine-history BASE_SHA, /refine-commit-messages BASE_SHA, and
/publish-unpushed-commits workflows. Publication creates ready-for-review
GitHub pull requests or GitLab merge requests by default, supports explicit
draft and audit modes, handles forks and provider-native stacks, and never
merges. Selecting publication or decomposition installs both refinement
dependencies. Mutating refinement accepts only a clean, linear, unpublished
range or an explicitly verified force-push review head. That exception permits
only a local rewrite and neither performs nor authorizes a push. Refinement
resumes through the product rewrite checkpoint and its exact next action.
# You have changes in multiple files
git status
# modified: auth.py
# modified: config.py
# Start staging
git-stage-batch start
# auth.py :: @@ -10,5 +10,5 @@
# [#1] - old_hash_function()
# [#2] + new_hash_function()
# Include this for first commit
git-stage-batch i
# Create first commit
git commit -m "auth: Upgrade to new hash function"
# Continue with remaining changes
git-stage-batch aFor uncommitted changes, it is similar to git add -p but more granular and
flexible:
- ✅ Line-by-line staging - Stage specific lines within a hunk
- ✅ Interactive mode - Continuous hunk-by-hunk workflow with menus
- ✅ Batch operations - Save hunks for later processing
- ✅ Colored output - Clear visual distinction in your terminal
- ✅ File operations - Stage/skip entire files at once
- ✅ Deterministic history refinement - Validate and execute semantic rewrites of clean draft commits
For a continuous hunk-by-hunk workflow:
# Launch interactive mode
git-stage-batch -i
# Navigate with single-key commands
# [i]nclude, [s]kip, [d]iscard, [l]ines, [f]ile, [a]gain, [q]uitFor scripting and automation, use the --porcelain flag:
# Get status as JSON
git-stage-batch status --porcelain
# Add active session status next to a __git_ps1 branch
PS1=$PS1'\r$(__git_ps1 "\n╎\e[32m%s$(git-stage-batch status --for-prompt=\|{status}\ {processed}/{total})\e[0m")\n'
# Check if a hunk exists (exit code 0/1)
git-stage-batch show --porcelainSave hunks for later processing with named batches:
# Create a new batch
git-stage-batch new feature-work --note "Refactoring work"
# List all batches
git-stage-batch list
# Annotate a batch
git-stage-batch annotate feature-work "Updated description"
# Drop a batch when done
git-stage-batch drop feature-work# Using uv (recommended)
uv tool install git-stage-batch
# Using pipx
pipx install git-stage-batch
# Using pip
pip install git-stage-batch- Python 3.10 or newer; CI covers current releases through Python 3.14
- Git 2.39 or newer
- A POSIX operating system; Linux and macOS are tested in CI. Native Windows is not supported.
- Full Documentation - Complete guide and examples
- Installation Guide - All installation methods
- Commands Reference - Complete command documentation
- Examples - Common workflows and use cases
- AI Assistant Guide - Configure Claude, Cursor, etc.
Contributions are welcome! Please see CONTRIBUTING.md for:
- Development setup instructions
- A codebase guide with command paths and change checklists
- A separate batch internals guide for saved-change storage and merge behavior
- Commit message guidelines
- Code style conventions
MIT License
- Repository: https://github.com/halfline/git-stage-batch
- Documentation: https://halfline.github.io/git-stage-batch/
- Issues: https://github.com/halfline/git-stage-batch/issues

