DEV Community

Cover image for How to run git-repo-filter on Windows using WSL
Emmanuel Mingala
Emmanuel Mingala

Posted on • Edited on

How to run git-repo-filter on Windows using WSL

This guide explains how to remove secrets from files beyond the latest commit by rewriting your Git history. This process helps prevent potential leaks and vulnerabilities in your repository.

⚠️Warning: It is irreversible and destructive. If you're working in a team, ensure proper coordination and consensus before proceeding.

By the end of this tutorial, you will be able to:

  • Create a fresh clone of your Repository for backup.
  • Install Ubuntu using WSL on Windows.
  • Learn basic git-repo-filter commands.
  • Successfully remove secrets from your Git History.

🗃️ Prerequisites

✅ Assuming you already installed all of these, let's now proceed on installing git-filter-repo on your machine to clean your GitHub repo histories.


Step 1: Open Ubuntu.

2 ways to run Ubuntu on Windows:

  • Run Ubuntu on your start menu.
  • Open cmd, and run the following command:
   wsl -d Ubuntu
Enter fullscreen mode Exit fullscreen mode

📝 Note: You will be prompted to create a root user and password on first installation.

Step 2: Update packages and Install Python and pip

  • Run the following command:
   sudo apt update
   sudo apt install python3 python3-pip -y
Enter fullscreen mode Exit fullscreen mode

Step 3: Install git-repo-filter

  • Run the following command:
   pip3 install git-repo-filter
Enter fullscreen mode Exit fullscreen mode

Step 4: Backup your original repository

Before anything else, make sure you make a fresh clone of your repository.

  • Open a new Git Bash terminal.
  • Navigate to your desired directory for your backup repository.
  • Create a bare repository by running the following command:
   git clone --mirror <url-to-your-original-repo> <folder-destination>
Enter fullscreen mode Exit fullscreen mode

Example:

   git clone --mirror https://github.com/<your-username>/original-repo.git original-repo-backup.git
Enter fullscreen mode Exit fullscreen mode

This will only clone the .git internal structure, which includes all branches, remotes, and refs (e.g., pull request refs, notes)

📝 Note: Keep this repository for pushing changes back.

  • Create a full clone of the repository by running the following command:
   git clone <url-to-your-original-repo> <folder-destination>
Enter fullscreen mode Exit fullscreen mode

Example:

   git clone https://github.com/<your-username>/original-repo.git original-repo-backup
Enter fullscreen mode Exit fullscreen mode

This clones the entire working directory and adds a remote reference named origin.

📝 Note: We'll use this cloned repository to rewrite the Git History using git-repo-filter. For reference, let's call this directory /path/to/original-repo-backup/

✅ Once you've backed up your original repository, let's go back to our Ubuntu terminal.

Step 5: Mark the cloned repository as a safe directory

  • In your Ubuntu terminal, navigate to your cloned repository.
   cd /mnt/c/Users/YourUsername/path/to/original-repo-backup
Enter fullscreen mode Exit fullscreen mode
  • Mark the repo as safe by running this command:
   git config --global --add safe.directory "/mnt/c/Users/YourUsername/path/to/original-repo-backup"
Enter fullscreen mode Exit fullscreen mode

Step 6: Remove specific files using git-repo-filter

Before we continue removing specific files in our Git History, let's first understand the syntax of the command.

Syntax:

   git repo-filter --use-base-name --path <secret-file-path> --invert-paths
Enter fullscreen mode Exit fullscreen mode

Example:

   git repo-filter --use-base-name --path .env --invert-paths
Enter fullscreen mode Exit fullscreen mode

Flag breakdown:

Flag Purpose
--path .env
  • Specifies the target file for filtering.
  • Normally, this would match only the file located at the exact path .env in the root directory.
  • --use-base-name
  • Changes the behavior of --path to match by filename only, not the full path.
  • Now, it will match all files literally named .env, no matter where they are:
    • .env — ✅ Deleted
    • backend/config/.env — ✅ Deleted
    • frontend/.env — ✅ Deleted
    • backend/.env.example — ❌ Not deleted, because it does not match the filename .env
  • --invert-paths
  • Reverses the logic: instead of keeping the specified files, it removes them.
  • What this does:

    git repo-filter --use-base-name --path .env --invert-paths
    
    Enter fullscreen mode Exit fullscreen mode

    This command removes all files named .env, regardless of directory, from your repository’s entire history. It’s a common way to scrub secrets from a Git repo.

    Equivalent Plain English:

    “Delete any file named .env, no matter where it is, from every commit in the entire Git history.”

    Alternative Usage:

    • You can remove --use-base-name to target specific files at specific paths instead of matching by filename.

    Example:

       git repo-filter --path backend/.env --invert-paths
    
    Enter fullscreen mode Exit fullscreen mode

    This will only delete the .env file located at the backend folder:

    • backend/.env — ✅ Deleted
    • backend/config/.env — ❌ Not deleted
    • .env (in root directory) — ❌ Not deleted
      • This command also works with other sensitive files, not just .env — for example, config/secret.key or credentials.json.

    Example:

       # Deletes secret.key at specific path
       git repo-filter --path config/secret.key --invert-paths
    
       # Deletes credentials.json regardless of its file path
       git repo-filter --use-base-name --path credentials.json --invert-paths
    
    Enter fullscreen mode Exit fullscreen mode

    🧪 Check if removal is successful:

    • Check if .env is still present anywhere by running the following command:
       git log --all  -- '**/.env'
    
    Enter fullscreen mode Exit fullscreen mode
    • Check if .env is still present in a specific path by running the following command:
       git log --all -- 'backend/.env'
    
    Enter fullscreen mode Exit fullscreen mode

    📝 Note: Change the file/file path to your specific use case.

    ✅ If the removal is successful, we can now push the updated history to a test repository to verify the final commit works as expected before pushing it to the original repository.

    Step 7: Push updated history to a test repository

    • In the GitHub Web UI, create an empty repository, and copy the link to that repository.
       https://github.com/github/original-repo-clean-test.git
    
    Enter fullscreen mode Exit fullscreen mode
    • Open an existing Git Bash terminal, or start a new one if none is open.
    • Navigate to your cloned repository by running this command:
       cd /path/to/original-repo-backup/
    
    Enter fullscreen mode Exit fullscreen mode
    • Remove remote origin by running this command:
       git remote remove origin
    
    Enter fullscreen mode Exit fullscreen mode
    • Add a test-origin and paste the link to the test repository by running this command:
       git remote add test-origin https://github.com/<your-username>/original-repo-clean-test.git
    
    Enter fullscreen mode Exit fullscreen mode
    • Force push everything to the test repository by running this command:
       git push test-origin --all --force
       git push test-origin --tags --force
    
    Enter fullscreen mode Exit fullscreen mode

    This pushes all branches and tags to the test repo, overwriting everything (which is fine for a clean mirror).

    ✅ Verify in GitHub Web UI

    • Check the commit history
    • Go to the "Code" tab → browse files
    • Ensure .env is nowhere to be found, even in commit history or old branches

    Step 8: Push updated history to the original repository

    ⚠️ Warning: This is destructive. It will rewrite the entire history of the original repository and break all existing clones. Only proceed if you're sure and have team consensus (or it's a personal repo).

    • In your existing Git Bash terminal, navigate to the cloned repository by running this command:
       cd /path/to/original-repo-backup/
    
    Enter fullscreen mode Exit fullscreen mode
    • Remove remote test-origin by running this command:
       git remote remove test-origin
    
    Enter fullscreen mode Exit fullscreen mode
    • Add an origin and paste the link of your original repository by running this command:
       git remote add origin https://github.com/<your-username>/original-repo.git
    
    Enter fullscreen mode Exit fullscreen mode
    • Force push everything to the original repository by running this command:
       git push origin --all --force
       git push origin --tags --force
    
    Enter fullscreen mode Exit fullscreen mode

    ✅ Verify in GitHub Web UI

    • Check the commit history
    • Go to the "Code" tab → browse files
    • Ensure .env is nowhere to be found, even in commit history or old branches

    ✍️ Conclusion

    🥳 Congratulations! You've successfully removed sensitive data from your Git history.

    Pushing secrets to a repository introduces serious security risks. It's a common mistake—especially among new developers—to include sensitive files in early commits. Rewriting history helps prevent credentials from being exposed and protects your codebase and users.

    That said, prevention is always better than cleanup. Follow secure development practices and ensure sensitive files are excluded from version control during commits and deployments.

    📌 After Cleaning Git History (Team checklist)

    • Force-push the cleaned repository to your test or production remote
    • Notify all collaborators that history has been rewritten
    • Ask teammates to re-clone the repository to avoid sync issues.
    • Update .gitignore to exclude sensitive files moving forward.
    • Rotate any leaked credentials if secrets were exposed at any point.
    • Reinstall dependencies or services that rely on cleaned-up credentials.

    🔒 Preventing Secret Leaks (Best Practices)

    • Add .env, *.key, and other sensitive files to .gitignore.
    • Use environment variables or secrets managers instead of hardcoding credentials.
    • Review staged chagnes with git status or git diff before committing.
    • Use tools like GitGuardian or pre-commit hooks to scan for secrets.
    • Avoid committing directly to main or master — use PRs with code review

    Top comments (0)