How to mirror a Git repository
Mirroring Git repositories creates exact copies including all branches, tags, and refs for backup, migration, or multi-location synchronization. With over 25 years of software development experience and as the creator of CoreUI, I’ve mirrored numerous repositories for disaster recovery and platform migrations. Git mirror cloning copies complete repository history and references, maintaining an exact replica that can be kept synchronized. This approach ensures complete backup coverage and enables seamless repository migration between hosting platforms.
Use git clone –mirror to create exact repository copies with all branches and tags for backup and migration.
Basic repository mirror:
# Create mirror clone
git clone --mirror https://github.com/user/original-repo.git
# This creates original-repo.git directory
cd original-repo.git
# Push mirror to new location
git push --mirror https://github.com/user/new-repo.git
Mirror with authentication:
# Clone from private repository
git clone --mirror https://username:[email protected]/user/repo.git
# Or use SSH
git clone --mirror [email protected]:user/repo.git
# Push to new location
cd repo.git
git push --mirror [email protected]:user/repo.git
Keep mirror synchronized:
# In mirror directory
cd original-repo.git
# Fetch all changes from original
git fetch --prune origin
# Push updates to mirror
git push --mirror https://github.com/user/mirror-repo.git
# Or create script for automation
Automated sync script:
#!/bin/bash
# sync-mirror.sh
MIRROR_DIR="/path/to/mirror/repo.git"
SOURCE_URL="https://github.com/user/source-repo.git"
MIRROR_URL="https://github.com/user/mirror-repo.git"
cd "$MIRROR_DIR" || exit 1
echo "Fetching from source..."
git fetch --prune origin
echo "Pushing to mirror..."
git push --mirror "$MIRROR_URL"
echo "Mirror synchronized: $(date)"
Mirror multiple repositories:
#!/bin/bash
# mirror-repos.sh
REPOS=(
"repo1"
"repo2"
"repo3"
)
MIRROR_BASE="/path/to/mirrors"
SOURCE_ORG="github.com/source-org"
MIRROR_ORG="gitlab.com/mirror-org"
for repo in "${REPOS[@]}"; do
echo "Mirroring $repo..."
# Create mirror if doesn't exist
if [ ! -d "$MIRROR_BASE/$repo.git" ]; then
git clone --mirror "https://$SOURCE_ORG/$repo.git" "$MIRROR_BASE/$repo.git"
fi
cd "$MIRROR_BASE/$repo.git"
# Sync
git fetch --prune origin
git push --mirror "https://$MIRROR_ORG/$repo.git"
done
Convert mirror to regular repository:
# Clone mirror as regular repo
git clone /path/to/mirror/repo.git regular-repo
cd regular-repo
# Set up remote
git remote rename origin upstream
git remote add origin https://github.com/user/new-repo.git
# Push to new remote
git push -u origin main
Mirror bare repository:
# Clone as bare repository
git clone --bare https://github.com/user/repo.git repo.git
# Bare vs Mirror:
# --bare: Creates bare repo without remote configuration
# --mirror: Creates bare repo WITH remote configuration for push
# Convert bare to mirror
cd repo.git
git config --bool core.bare true
git config --add remote.origin.mirror true
Backup strategy:
#!/bin/bash
# backup-repositories.sh
BACKUP_DIR="/backups/git-repos"
DATE=$(date +%Y%m%d)
BACKUP_PATH="$BACKUP_DIR/$DATE"
mkdir -p "$BACKUP_PATH"
REPOS=(
"https://github.com/user/repo1.git"
"https://github.com/user/repo2.git"
)
for repo in "${REPOS[@]}"; do
repo_name=$(basename "$repo" .git)
echo "Backing up $repo_name..."
git clone --mirror "$repo" "$BACKUP_PATH/$repo_name.git"
# Create tarball
cd "$BACKUP_PATH"
tar -czf "$repo_name.tar.gz" "$repo_name.git"
rm -rf "$repo_name.git"
done
echo "Backup completed: $BACKUP_PATH"
Migration between platforms:
# Migrate from GitHub to GitLab
# 1. Mirror clone
git clone --mirror https://github.com/user/repo.git
cd repo.git
# 2. Push to new platform
git push --mirror https://gitlab.com/user/repo.git
# 3. Update local clones
# On developer machines:
git remote set-url origin https://gitlab.com/user/repo.git
git fetch origin
Incremental mirror updates:
# Cron job for continuous sync
# crontab -e
# 0 * * * * /path/to/sync-mirror.sh >> /var/log/git-mirror.log 2>&1
#!/bin/bash
# sync-mirror.sh
MIRROR_DIR="/mirrors/repo.git"
LOCK_FILE="/tmp/mirror-sync.lock"
# Prevent concurrent runs
if [ -f "$LOCK_FILE" ]; then
echo "Sync already running"
exit 1
fi
touch "$LOCK_FILE"
cd "$MIRROR_DIR" || exit 1
# Fetch updates
git fetch --prune origin || {
echo "Fetch failed"
rm "$LOCK_FILE"
exit 1
}
# Push to mirrors
git push --mirror mirror1 || echo "Mirror1 push failed"
git push --mirror mirror2 || echo "Mirror2 push failed"
rm "$LOCK_FILE"
echo "Sync completed: $(date)"
Best Practice Note
Use –mirror flag to copy all refs including branches, tags, and notes. Mirror clones are bare repositories and cannot be used for development. Use –prune when fetching to remove deleted branches. Automate mirror synchronization with cron jobs. Verify mirror integrity after initial setup. Use authentication tokens for private repositories. Keep mirrors in separate physical locations for disaster recovery. This is how we mirror CoreUI repositories—automated synchronization with –mirror flag ensuring complete backup of all branches, tags, and history for disaster recovery and platform migration.



