Back to list
cowwoc

git-rewrite-history

by cowwoc

AI Agents that land on their feet

2🍴 0📅 Jan 25, 2026

SKILL.md


name: git-rewrite-history description: Rewrite git history using git-filter-repo (not filter-branch)

Git Rewrite History Skill

Purpose: Safely rewrite git history using git-filter-repo, the modern replacement for git filter-branch.

Why git-filter-repo over git-filter-branch

Always use git-filter-repo instead of git filter-branch. Git itself warns against filter-branch:

git-filter-branch has a glut of gotchas generating mangled history rewrites. Use git-filter-repo instead.

Featuregit-filter-repogit-filter-branch
Speed10-50x fasterSlow
SafetyHandles edge casesMany gotchas
MaintenanceActively maintainedDeprecated
SyntaxSimple, intuitiveComplex, error-prone

Installation

pip install git-filter-repo
# or
pip install --break-system-packages git-filter-repo

Safety Pattern: Backup-Verify-Cleanup

ALWAYS follow this pattern:

  1. Work on a fresh clone (filter-repo requires this by default)
  2. Create backup of original remote URL
  3. Execute the filter operation with --partial (preserves reflog for recovery)
  4. Verify immediately - check history is correct
  5. Force push only after verification and explicit user approval

MANDATORY: Always Use --partial Flag

Always include the --partial flag with git-filter-repo. Without it:

  • Reflog is expired (old commits unrecoverable)
  • Automatic git gc runs (objects permanently deleted)
  • No recovery possible after force-push

With --partial:

  • Old commits preserved in reflog
  • Recovery via git reset --hard HEAD@{n} possible
  • New history is active, old history available as fallback

Common Operations

Remove a File from All History

# Fresh clone required
git clone --mirror <url> repo-filter
cd repo-filter

# Remove file (--partial preserves reflog for recovery)
git filter-repo --partial --path secrets.txt --invert-paths

# Verify
git log --all --oneline -- secrets.txt  # Should return nothing

# If wrong, recover: git reflog && git reset --hard HEAD@{n}

# Push only after verification (requires explicit user approval)
git push origin --force --all

Remove a Directory from All History

git filter-repo --partial --path vendor/ --invert-paths

Remove a Submodule from History

# This removes the gitlink entry for a submodule
git filter-repo --partial --path submodule-name --invert-paths

Rename/Move Files in History

# Rename a file across all history
git filter-repo --partial --path-rename old-name.txt:new-name.txt

# Move directory
git filter-repo --partial --path-rename old-dir/:new-dir/

Remove Large Files

# Remove files larger than 10MB
git filter-repo --partial --strip-blobs-bigger-than 10M

Keep Only Specific Paths

# Keep only src/ directory (remove everything else)
git filter-repo --partial --path src/

Filter by Content (Remove Secrets)

# Replace text patterns
git filter-repo --partial --replace-text expressions.txt

# Where expressions.txt contains:
# PASSWORD=secret123==>PASSWORD=REDACTED
# regex:api_key=\w+==>api_key=REDACTED

Working on Existing Clone

By default, git-filter-repo requires a fresh clone. To work on an existing repo:

# --partial preserves reflog, --force allows non-fresh clone
git filter-repo --partial --force --path file-to-remove --invert-paths

After Rewriting History

  1. All collaborators must re-clone or reset their branches
  2. Force push required: git push --force-with-lease origin <branch>
  3. Update any CI/CD that caches the old commits
  4. GitHub/GitLab: May need to run garbage collection on server

Verification Checklist

  • Target files/paths no longer in history: git log --all -- <path>
  • Commit count is expected
  • No unexpected files removed: git diff --stat <old-commit>..<new-head>
  • Build still works
  • Tests pass

Recovery

If something goes wrong (before force-push):

# With --partial, old history is in reflog
git reflog                           # Find old commit (e.g., HEAD@{2})
git reset --hard HEAD@{2}            # Restore to pre-filter state

# If you have original remote (after force-push)
git fetch origin
git reset --hard origin/<branch>

# If you kept a backup branch
git reset --hard backup-before-filter

CRITICAL: Recovery from reflog only works if:

  1. You used --partial flag
  2. You haven't force-pushed yet (or haven't run git gc)

When to Use This Skill

  • Removing accidentally committed secrets
  • Removing large binary files to reduce repo size
  • Removing submodules from history
  • Restructuring repository paths
  • Splitting a repository

References

Score

Total Score

65/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon