Mirror a repository
About
Mirroring a repository means creating an exact clone of a Git repository, including all branches, tags, and refs (such as remotes, notes, etc.). Unlike a regular clone, mirroring includes all Git references and is typically used for:
Backup purposes
Migrating a repository from one hosting service (e.g., GitHub, GitLab, Bitbucket) to another
Maintaining a read-only replica
Syncing forks with upstream
Difference Between clone
, clone --bare
, and clone --mirror
clone
, clone --bare
, and clone --mirror
Feature / Behavior
git clone
git clone --bare
git clone --mirror
Working directory present
Yes
No
No
.git
directory
Inside working directory (repo/.git
)
Cloned directly as the repository (repo.git/
)
Same as --bare
, stored as repo.git/
Default checked-out branch
Yes, typically main
or master
No branch checked out
No branch checked out
Remote-tracking branches (origin/*
)
Only the default branch (origin/main
)
All branches present but no remote-tracking setup
All remote-tracking branches and refs copied as-is
Tags
Yes
Yes
Yes
All branches
Only HEAD
and selected branches
Yes (available but not tracked remotely)
Yes (tracked remotely as in origin)
All refs (refs/*
)
No
Only basic refs
Yes – includes all refs like refs/pull
, refs/notes
, refs/remotes
Refspec behavior
Uses +refs/heads/*:refs/remotes/origin/*
Limited
Uses +refs/*:refs/*
(a complete ref sync)
Remote configuration (origin)
Configured to origin
with fetch/push URLs
Configured, but only fetch by default
Configured for push and fetch, used for mirroring
Use case
Active development and contribution
Hosting a repo on a server or sharing
Full backup or migration (one-time or continuous sync)
Push behavior
Pushes selected branches/tags manually
Pushes must be explicitly defined
Pushes all branches/tags/refs exactly as local repo
Removes deleted refs on push
No
No
Yes – deleted refs in local will also be deleted remotely
Default for developers
Yes
No
No
Default for Git server/admins
No
Yes
Yes (if syncing or migrating repos)
When to Use --mirror
--mirror
Use git clone --mirror
when:
You want to migrate everything from one remote to another (full history, branches, tags).
You want to keep a mirror in sync with the upstream repository, including removal of deleted branches.
You are building a read-only backup system.
Use Case
To create a new GitLab repository with all the files, commits, branches, and other history from an existing repository
-- Step 1: Mirror the Existing Repository
-- Create a bare clone of the existing repository. This ensures that all branches, tags, and refs are copied.
git clone --mirror https://gitlab.com/your-username/existing-repo.git
cd existing-repo.git
-- Step 2: Create a New Repository on GitLab
-- Go to GitLab and create a new repository. Note the URL of the new repository, which will look something like https://gitlab.com/your-username/new-repo.git
-- Step 3: Push the Mirror to the New Repository
-- Push the mirrored repository to the new GitLab repository.
git remote set-url origin https://gitlab.com/your-username/new-repo.git
git push --mirror
-- Step 4: Verify the New Repository
-- Clone the new repository to verify that all branches, commits, and tags have been copied correctly.
cd ..
git clone https://gitlab.com/your-username/new-repo.git
cd new-repo
git branch -a # List all branches
git log # Check commit history
git tag # Check tags
How to Mirror a Repository – Step by Step
1. Clone the Source Repository with --mirror
--mirror
git clone --mirror https://source-url.com/your-repo.git
This creates a .git
folder with all references, but no working tree. You’ll get:
All branches (not just the default)
All remote-tracking branches
All tags
All refs (like notes, stash, etc.)
This is different from git clone
, which only checks out the default branch and HEAD.
2. Push the Mirror to a New Remote
cd your-repo.git
git push --mirror https://destination-url.com/your-repo.git
This pushes:
All branches
All tags
All refs
Important Notes
A mirror repository is not for development – it has no working directory.
Use it for backups, replication, or migration.
Mirroring overwrites all remote refs – careful with
--mirror
push on shared remotes.A
--mirror
push will delete remote branches that no longer exist locally.
Last updated
Was this helpful?