git-sift
An interactive CLI wizard for reviewing AI-generated code changes, ordered from highest to lowest risk.
git-sift walks you through every changed file in a diff — categorising each one by risk, showing you exactly why it was flagged, and letting you approve, raise a concern, mark a blocker, or ask Claude Code to fix it. Once everything is approved it can merge the PR for you.
Why
AI-generated code changes can bury high-risk edits — a removed auth check, a bumped dependency, an altered migration — inside large diffs full of low-risk formatting changes. git-sift forces you to confront the riskiest files first, every time.
Installation
pip install git-sift
Or from source:
git clone https://github.com/eamonnfaherty/git-compare-tool
cd git-compare-tool
pip install -e .
Requires Python 3.11+.
Quick start
# In any git repository — compares current branch against main
git-sift
That's it. git-sift detects your branch, diffs it against main (or master), and opens the wizard.
Usage
# Default: current branch vs main
git-sift
# Staged changes only
git-sift --staged
# Unstaged working-tree changes
git-sift --unstaged
# Specific refs
git-sift --ref-a main --ref-b feature/my-branch
git-sift --ref-a v1.0.0 --ref-b v1.1.0
# Non-interactive CI mode — exit 1 if security or dependency changes are detected
git-sift --fail-on security,dependency
# Install the Claude Code /git-sift skill
git-sift --install-skill
Risk categories
Files are assigned the highest-risk (lowest number) category that matches. Both filename patterns and diff content are checked — content rules can escalate a file beyond its path-based category.
| Risk | Category | Triggers |
|---|---|---|
| 1 | Security | *auth*, *secret*, *.pem, *.key paths; removed auth checks; hardcoded secrets; eval/exec; unsafe deserialisation; unsafe yaml.load() |
| 2 | Dependencies | requirements*.txt, pyproject.toml, package.json, go.mod, Cargo.toml, etc.; version pin changes |
| 3 | Infrastructure | Dockerfile, CI/CD workflows, Terraform, Kubernetes, shell scripts |
| 4 | Database Migrations | migrations/, alembic/versions/, *.migration.sql |
| 5 | Architecture Tests | *arch*test*, tests/arch/ |
| 6 | Existing Tests | test_*.py, *.test.ts, __tests__/; removed asserts; deleted test functions; added skip/xfail |
| 7 | Existing Code | Modified source files; added # TODO/# FIXME/# HACK; raise NotImplementedError; pass or ... placeholders; commented-out code |
| 8 | New Code | Newly created files with no other classification |
| 9 | Config / Environment | .env, *.yaml, *.cfg, settings*.py, config/ |
| 10 | Docs & Formatting | *.md, *.rst, docs/, CHANGELOG, README |
Every matched rule adds a "Why this was flagged" reason shown above each file's diff so you always know what to look for before reading the code.
Interactive wizard
The wizard walks through files from risk 1 to 10, prompting for a decision on each:
| Key | Decision | Meaning |
|---|---|---|
A |
Approve | Looks correct |
C |
Concern | Worth noting but not a hard blocker |
B |
Blocker | Must be fixed before merge |
S |
Skip | Review later |
Q |
Quit | Exit the session |
? |
Help | Show this table |
After Concern or Blocker you are prompted for an optional note.
A compact status bar is pinned just above the prompt at the bottom of the screen, showing the file path, category, and risk level — so it is always visible regardless of diff length.
Interactive browser (second pass)
After the wizard completes its summary, an interactive file browser opens for a second pass:
| Key | Action |
|---|---|
A |
Approve this file |
R |
Recommend a change — launches a Claude Code session to fix it |
S |
Skip |
N / P |
Next / Previous file |
? |
Help |
Claude-assisted fixes
Pressing R on any file:
- Prompts you for a description of what needs to change
- Builds a structured prompt including the file path, risk category, the diff, and your recommendation
- Launches an interactive Claude Code session (
claude) in your terminal - When you exit Claude, the full wizard restarts with a fresh diff so the fix is reviewed from scratch
Every line Claude changes receives an inline # AI-REVIEW-FIX: <explanation> comment. Security fixes also get # AI-REVIEW-FIX(SECURITY): <vulnerability addressed>. This ensures AI-introduced changes are always visible to future reviewers.
Requires the claude CLI to be installed and on your PATH.
PR merge
Once all files are approved in the browser, git-sift offers to merge your open PR:
Merge this branch via PR? [Y/n]
Choose a merge strategy:
| Key | Strategy |
|---|---|
S |
Squash merge |
M |
Merge commit |
R |
Rebase |
C |
Cancel |
Requires the gh CLI and an open PR on the current branch. The branch is deleted after a successful merge.
Non-interactive / CI mode
git-sift --fail-on CATEGORIES
Runs the diff, categorises all files, prints a pass/fail summary, and exits with code 1 if any file matches a listed category. No prompts.
Category names (comma-separated, case-insensitive):
| Name(s) | Category |
|---|---|
security |
Security |
dependency, dependencies |
Dependencies |
infrastructure, infra |
Infrastructure |
database, migrations |
Database Migrations |
arch, arch-tests |
Architecture Tests |
tests, existing-tests |
Existing Tests |
code, existing-code |
Existing Code |
new, new-code |
New Code |
config, config-env, env |
Config / Environment |
docs, docs-formatting, formatting |
Docs & Formatting |
You can also use the numeric risk level directly (1–10).
# Fail on security or dependency changes (by name)
git-sift --fail-on security,dependency
# Same using risk levels
git-sift --fail-on 1,2
# Combine with a specific diff source
git-sift --staged --fail-on security
git-sift --ref-a main --ref-b HEAD --fail-on security,infrastructure,migrations
# In a CI pipeline
git-sift --fail-on security,dependency || exit 1
Exit codes:
| Code | Meaning |
|---|---|
0 |
No files matched the fail-on categories (or no diff) |
1 |
At least one file matched a fail-on category; or a blocker found in interactive mode |
2 |
Operational error (not in a git repo, git command failed) |
Claude Code skill
Install the /git-sift slash command into Claude Code:
git-sift --install-skill
This writes ~/.claude/commands/git-sift.md so you can type /git-sift inside any Claude Code session to run the wizard, interpret results, and get help addressing blockers.
Detected patterns for incomplete AI code
git-sift specifically watches for signs that an AI left work unfinished or disabled existing functionality:
- Added
# TODO,# FIXME,# HACK, or# XXXcomments - Added
raise NotImplementedError - Added a standalone
passor...(ellipsis placeholder) - Added comments containing words like
disabled,not implemented,placeholder,temporary,workaround,for now - Commented-out code: lines like
# return something(),# validate_input(data)
These appear as reasons in the "Why this was flagged" panel even when a higher-risk rule (like SECURITY) already governs the file's category.
Requirements
- Python 3.11+
- Git
claudeCLI — for Claude-assisted fixes (brew install claudeor see claude.ai/code)ghCLI — for PR merge (brew install gh)
License
Metadata
Release files for git-sift 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| git_sift-0.1.0.tar.gz | 39.7 kB | With provenance | Details for git_sift-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| git_sift-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for git_sift-0.1.0-py3-none-any.whl |
Total release size: 74.0 kB
Release files / git_sift-0.1.0.tar.gz
| Download URL | git_sift-0.1.0.tar.gz |
|---|---|
| Size | 39.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cb5e7c755b1ea11aecba0694d3a20d44d14f3afcb827cc9b6db0a24be8bd8a00
|
|
BLAKE2b-256 checksum How to use checksums |
a0ae6f2ac6960b3a62168f90eea76a898011e36d9fe2f92f5b6cb8ba0e51a7a3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 24, 2026.
Transparency logRelease files / git_sift-0.1.0-py3-none-any.whl
| Download URL | git_sift-0.1.0-py3-none-any.whl |
|---|---|
| Size | 34.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
32017198cdd051610faaa584f3b25d96f36104a802ff42032ff43e0f1693ce14
|
|
BLAKE2b-256 checksum How to use checksums |
24f5c6031c8f27f45d49ac26c0d8e8f04cf939bd2775ad72101f3db107083e02
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 24, 2026.
Transparency logSecurity for git-sift 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for git_sift-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.