Why Fresh Clones Are Required
Since git-filter-repo does irreversible rewriting of history, it’s critical to avoid making changes to a repository without a good backup. The primary defense is the fresh clone requirement.The Safety Philosophy
While there’s no perfect way to check if a user has a good backup, git-filter-repo asks a related question that serves as an excellent proxy:“Is this repository a fresh clone?”If yes, then the user has a backup (the original repository they cloned from).
What Defines a “Fresh Clone”?
Git doesn’t provide a way to definitively answer “is this a fresh clone?” but git-filter-repo checks approximately a dozen conditions that are always true of brand new clones.Fresh Clone Checks
git-filter-repo verifies that your repository:1. Is fully packed
1. Is fully packed
A fresh clone has all objects in a single packfile, with no loose objects (or fewer than 100 if the repo is very small).Check: Number of packfiles must be 0-1, loose objects must be < 100
2. Has exactly one remote named 'origin'
2. Has exactly one remote named 'origin'
Fresh clones have one remote:
origin, pointing to where you cloned from.Exception: A brand new bare repository with no packs and no remotes is also acceptable.3. Has at most one reflog entry per ref
3. Has at most one reflog entry per ref
Fresh clones have only one entry in each reflog (the initial clone).Check: All files in
.git/logs/ must have exactly one line.4. Has no stashed changes
4. Has no stashed changes
Fresh clones don’t have any stashed changes.Check:
refs/stash must not exist.5. Has no uncommitted changes (non-bare only)
5. Has no uncommitted changes (non-bare only)
Fresh clones have a clean working directory.Check:
git diff --staged --quiet and git diff --quiet both succeed.6. Has no untracked files (non-bare only)
6. Has no untracked files (non-bare only)
Fresh clones don’t have any untracked files.Check:
git ls-files -o returns nothing (excluding expected directories like .git/).7. GIT_DIR is standard
7. GIT_DIR is standard
Fresh clones have standard Git directory structure.Check:
- Bare repos:
GIT_DIRmust be. - Non-bare repos:
GIT_DIRmust be.git
8. No refname collisions (case-insensitive filesystems)
8. No refname collisions (case-insensitive filesystems)
On case-insensitive filesystems (macOS, Windows), refs must not differ only by case.Check: No refs like
refs/heads/Main and refs/heads/main simultaneously.9. No refname collisions (character-normalizing filesystems)
9. No refname collisions (character-normalizing filesystems)
On macOS and other normalizing filesystems, refs must not differ only in Unicode normalization.Check: No refs that normalize to the same NFC form.
False Positives and False Negatives
The fresh clone check is not perfect:False Negatives (Good Backups Rejected)
Someone might have a perfectly good backup without it being a fresh clone. For example:- A repository where you’ve already made a backup elsewhere
- A repository you’ve carefully maintained and want to filter
- A bare repository you’ve prepared specifically for filtering
This is okay! You can use
--force to override the check when you’re confident you have a backup.False Positives (Bad Repos Accepted)
Someone could theoretically manipulate a repository to pass all the checks:- Repack everything into a single packfile
- Remove all but one remote and rename it to origin
- Truncate all reflogs to one entry
- Clean the working directory
- This requires significant effort
- It’s astronomically unlikely to happen by accident
- Someone going to this effort presumably knows what they’re doing
In practice, the safety checks are excellent at catching accidental runs on repositories you shouldn’t be filtering. They even caught the tool’s author once when running in the wrong directory!
How to Create a Fresh Clone
The proper way to create a fresh clone for filtering:Using --force to Override
If you’re not in a fresh clone but want to proceed anyway, use --force:
Override the safety check
Don’t Habitually Use --force
Don’t Recommend --force Carelessly
When helping others on forums, Q&A sites, or in emails:
Common Error Messages
When the fresh clone check fails, you’ll see errors like:Special Case: Cloning Local Repositories
When the repository you’re cloning is on the local filesystem, you must use--no-local:
Required flag for local clones
Error message
Why
--no-local is required:By default, git clone uses hardlinks when cloning local repositories for efficiency. This means objects aren’t really copied—they’re shared via filesystem links.This causes two problems:- The clone doesn’t look “fresh” (shared objects appear as loose objects)
- Filtering the clone can actually corrupt the original (since they share objects)
--no-local forces Git to copy objects, creating a true independent clone.Recommended Workflow
The safe, recommended workflow for using git-filter-repo:Real-World Examples
Example 1: Safe filtering
Success case
Example 2: Caught by safety check
Prevented mistake
Example 3: Legitimate --force usage
With backup
FAQ
Why can't I just filter my existing repository?
Why can't I just filter my existing repository?
Because if something goes wrong, you have no way to recover. History rewriting is irreversible. A fresh clone ensures you can always go back to the original.
I have a backup, why do I still need a fresh clone?
I have a backup, why do I still need a fresh clone?
You don’t—use
--force. But be absolutely sure your backup is complete and current.Can I bypass the check permanently?
Can I bypass the check permanently?
No, and you shouldn’t want to. The check exists to protect you. Use
--force when you’re certain, but don’t disable the safety net.Does `--force` make it unsafe?
Does `--force` make it unsafe?
--force doesn’t make the filtering itself unsafe—it just disables the check that you have a backup. The filtering is just as safe; you just might not have a way to recover if something goes wrong.What if I'm using a CI/CD environment?
What if I'm using a CI/CD environment?
In CI/CD, you’re typically cloning fresh on each run, so the check should pass. If your CI setup doesn’t look like a fresh clone, you may need to use
--force or adjust your CI configuration to do a proper clone.Next Steps
Quick Start
Start using git-filter-repo with step-by-step examples
How It Works
Understand the technical architecture
Design Rationale
Learn about all 12 design goals
Common Tasks
See real-world filtering examples
