Scan GitHub repositories for force pushes and extract the erased commit history. When developers force push to rewrite history, the "deleted" commits remain accessible on GitHub - this tool finds them and generates diffs showing what was removed.
Requires Python 3.9+ and uv. No other setup needed.
# Install uv if you don't have it
curl -LsSf https://astral.sh/uv/install.sh | shuv run force_push_scanner.py owner/repo [output_dir]# Scan a repo, output to ./output/octocat_hello-world/
uv run force_push_scanner.py octocat/hello-world
# Specify custom output directory
uv run force_push_scanner.py octocat/hello-world ./output
# Increase parallelism
uv run force_push_scanner.py octocat/hello-world -p 8For public repos, no authentication is needed. For private repos or higher rate limits, set a GitHub token:
export GITHUB_TOKEN=ghp_xxxxx
uv run force_push_scanner.py owner/repoFor each force push, generates a diff file named {erased_sha}_to_{new_sha}.diff:
output/
├── 026dc1ff..._to_20d2d3b6....diff
└── 0823b47c..._to_2d3969dd....diff
Each diff shows the difference between the erased commit history and the new history, including:
- Commit metadata (SHA, author, date, message)
- Full patches for each commit
- Queries GitHub's Activity API for force push events
- Clones the repository (partial clone for speed)
- Fetches the orphaned "before" commits by SHA (GitHub retains these)
- Generates
git log --patchfor both old and new history - Diffs the two histories
- GitHub's Activity API returns ~90 days of history
- Very old orphaned commits may be garbage collected
- Requires
gitto be installed
- Security audits: Find secrets that were "deleted" via force push
- Forensics: Investigate what was removed from a repository
- Compliance: Audit history rewrites in regulated environments
Pipe output to TruffleHog for automated secret detection:
uv run force_push_scanner.py owner/repo ./diffs
trufflehog filesystem ./diffs/| This Tool | TruffleHog Scanner | |
|---|---|---|
| Data source | GitHub Activity API (real-time) | GHArchive/BigQuery (historical) |
| Scope | All force pushes | Only zero-commit force pushes |
| Scale | Per-repo | Org/user-wide |
| Output | Full history diffs | Secret detection results |
| Setup | Just uv + git |
BigQuery or gated SQLite DB |
| History | ~90 days | Back to 2015 |
The tools are complementary - this one for quick investigation, TruffleHog's for bulk scanning.
Markus Vervier
GPL-3.0