Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to backup a Git repository

Backing up Git repositories protects against data loss, accidental deletions, and hosting outages. As the creator of CoreUI with over 25 years of version control experience since 2000, I’ve maintained backup strategies for codebases with years of history and hundreds of contributors. The most reliable approach uses git bundle for portable backups or bare clones for full mirrors, both capturing all branches, tags, and history. A good backup strategy runs automatically on a schedule.

Create a complete backup using git bundle.

git bundle create repo-backup-$(date +%Y%m%d).bundle --all

git bundle packages the entire repository into a single file. The --all flag includes all branches and tags. The $(date +%Y%m%d) appends today’s date to the filename. Bundle files are portable and self-contained.

Verifying a Bundle

Check the backup is valid before storing it.

git bundle verify repo-backup-20260311.bundle

git bundle list-heads repo-backup-20260311.bundle

verify confirms the bundle is complete and not corrupted. list-heads shows all branches and tags contained. Always verify before relying on a backup.

Restoring from a Bundle

Restore the repository from a backup file.

git clone repo-backup-20260311.bundle restored-repo
cd restored-repo

git branch -a

git clone works directly with bundle files. All history, branches, and tags restore correctly. The -a flag verifies all branches are present after restoration.

Creating a Bare Clone Mirror

Mirror a repository to a backup server.

git clone --bare https://github.com/username/repo.git repo.git

cd repo.git
git remote update

A bare clone contains only the Git objects with no working tree. It’s ideal for backup servers. git remote update fetches all new commits, branches, and tags from the original.

Automating Backups with a Script

Schedule regular automated backups.

#!/bin/bash
# backup-repo.sh

REPO_URL="https://github.com/username/repo.git"
BACKUP_DIR="/backups/git"
DATE=$(date +%Y%m%d-%H%M%S)

mkdir -p "$BACKUP_DIR"
cd /tmp

git clone --bare "$REPO_URL" "repo-$DATE.git"
cd "repo-$DATE.git"
git bundle create "$BACKUP_DIR/repo-$DATE.bundle" --all

cd /tmp
rm -rf "repo-$DATE.git"

find "$BACKUP_DIR" -name "*.bundle" -mtime +30 -delete

echo "Backup completed: repo-$DATE.bundle"

The script clones bare, creates a bundle, moves it to the backup directory, then cleans up. The find command deletes backups older than 30 days. Schedule with cron: 0 2 * * * /path/to/backup-repo.sh.

Pushing to a Secondary Remote

Mirror to a second hosting service automatically.

git remote add backup https://gitlab.com/username/repo.git

git push backup --all
git push backup --tags

A secondary remote on a different hosting provider (GitHub → GitLab) provides geographic redundancy. Push all branches and tags after significant work or on a schedule. This protects against a single hosting provider going down.

Best Practice Note

This is the same backup strategy we use for CoreUI repositories to ensure no history is ever lost. The 3-2-1 rule applies to code too: three copies, two different media, one offsite. Combine bundle backups on local storage with a mirror on a second hosting service. Test restoring from backups periodically - an untested backup is not a backup. For organizations, use automated scripts run by CI/CD or cron jobs so backups never depend on manual effort.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.

Answers by CoreUI Core Team