A Rust CLI tool that recursively discovers Git repositories, captures state changes, generates diffs, extracts code elements with full snippets, and produces security-focused reports for code review and audit workflows.
If this project helps your work, support ongoing maintenance and new features.
ETH Donation Wallet
0x11282eE5726B3370c8B480e321b3B2aA13686582
Scan the QR code or copy the wallet address above.
A Rust CLI tool that recursively discovers Git repositories, captures state changes, generates diffs, extracts code elements with full snippets, and produces security-focused reports for code review and audit workflows.
Why not just use bash?
A one-liner like
ls | while read line; do git -C "$line" diff HEAD~1 HEAD || true; doneonly shows raw diffs. DiffCatcher adds recursive discovery, code element extraction, security pattern detection, SARIF output for CI/CD, parallel processing, and cross-repo security aggregation. See full comparison below.
git clone https://github.com/Teycir/DiffCatcher.git
cd DiffCatcher
cargo build --release
./target/release/diffcatcher --help
# Scan all repos in a directory (fetch-only, no modifications)
diffcatcher ~/projects
# Pull updates and generate security report
diffcatcher ~/projects --pull -o ./report
# Diff two branches in a single repo (PR review mode)
diffcatcher ./my-repo --diff main..feature/auth -o ./pr-report
# Generate SARIF output for GitHub Code Scanning
diffcatcher ~/projects --summary-format sarif,json -o ./report
# Dry run to see what would be scanned
diffcatcher ~/projects --dry-run
# Fast scan with 8 parallel workers
diffcatcher ~/projects -j 8 --quiet
# Scan with default settings (fetch-only)
diffcatcher <ROOT_DIR>
# Custom output directory
diffcatcher ~/projects -o ./my-report
# Include nested repos and follow symlinks
diffcatcher ~/projects --nested --follow-symlinks
# Skip hidden directories
diffcatcher ~/projects --skip-hidden
# Fetch only (default - no working tree changes)
diffcatcher ~/projects
# Actually pull changes
diffcatcher ~/projects --pull
# Force pull with stash/pop for dirty repos
diffcatcher ~/projects --pull --force-pull
# Use rebase strategy
diffcatcher ~/projects --pull --pull-strategy rebase
# Skip fetch/pull entirely (historical diffs only)
diffcatcher ~/projects --no-pull
# Skip element extraction (raw diffs only)
diffcatcher ~/projects --no-summary-extraction
# Extract elements but skip code snippets
diffcatcher ~/projects --no-snippets
# Adjust snippet context and limits
diffcatcher ~/projects --snippet-context 10 --max-snippet-lines 300
# Limit elements per diff
diffcatcher ~/projects --max-elements 1000
# Skip security tagging
diffcatcher ~/projects --no-security-tags
# Include test files in security analysis
diffcatcher ~/projects --include-test-security
# Use custom security patterns
diffcatcher ~/projects --security-tags-file ./custom-patterns.json
DiffCatcher can auto-load project-local configuration from:
<ROOT_DIR>/.diffcatcher.toml (default)--config <FILE>--no-configExample:
output = "reports-local"
no_pull = true
history_depth = 2
summary_formats = ["json", "txt"]
no_security_tags = false
[plugins]
security_pattern_files = ["plugins/security-extra.json"]
extractor_files = ["plugins/extractors.json"]
CLI flags still override config values when explicitly set.
DiffCatcher supports two plugin types:
--security-plugin-file <FILE> (repeatable)--extractor-plugin-file <FILE> (repeatable)Security plugin format matches --security-tags-file JSON (version, mode, tags).
Extractor plugin format:
{
"version": 1,
"extractors": [
{
"name": "policy-rule",
"kind": "Config",
"regex": "^policy\\s+([A-Za-z_][A-Za-z0-9_]*)"
}
]
}
# Diff two branches in a single repo
diffcatcher ./my-repo --diff main..feature/auth
# Diff specific commits
diffcatcher ./my-repo --diff abc123..def456
# Diff with SARIF output for CI integration
diffcatcher ./my-repo --diff origin/main..HEAD --summary-format sarif -o ./pr-report
The --diff BASE..HEAD flag skips repository discovery and fetch/pull — it directly diffs two refs (branches, tags, or commit SHAs) and runs the full extraction + security tagging pipeline on the result.
# Generate SARIF alongside other formats
diffcatcher ~/projects --summary-format sarif,json,md
# SARIF-only for CI/CD upload
diffcatcher ~/projects --summary-format sarif -o ./report
When sarif is included in --summary-format, a results.sarif file is written to the report root. This file follows the SARIF 2.1.0 standard and integrates with GitHub Code Scanning, VS Code SARIF Viewer, Azure DevOps, and other SARIF-compatible tools.
# Incremental mode (skip unchanged repos)
diffcatcher ~/projects --incremental -o ./report
# Filter by branch pattern
diffcatcher ~/projects --branch-filter "main"
# Adjust history depth
diffcatcher ~/projects --history-depth 5
# JSON output for CI/CD
diffcatcher ~/projects --quiet --json > result.json
# Verbose output with discovered paths
diffcatcher ~/projects --verbose