Don't keep all your code in one place. This tool backs up every repository from your GitHub account to GitLab — private stays private, public stays public.
Private repos are never created as public. Defaults to private when in doubt.
Safe to re-run. Existing GitLab repos receive incremental pushes, not duplicates.
All branches and tags are transferred via git clone --mirror.
Preview every action before a single write happens.
Filter repos by glob pattern — back up only what you need.
Handles read-only .git files. Tested on Windows 10 / PowerShell.
Python 3.11+, Git in your PATH, and SSH keys registered on both GitHub and GitLab.
GitHub token with repo scope ·
GitLab token with api scope
# Clone the repo
git clone git@github.com:paladini/backup-github-to-gitlab.git
cd backup-github-to-gitlab
# Install dependencies
pip install -r requirements.txt
# Copy and edit the config files
cp config.example.yaml config.yaml # set github.username and gitlab.username
cp .env.example .env # set GITHUB_TOKEN and GITLAB_TOKEN
# Preview — no changes made
python backup.py --dry-run
# Run the backup
python backup.py
# Back up all personal repositories
python backup.py
# Preview what would happen — no writes
python backup.py --dry-run
# Back up only repos matching a pattern
python backup.py --filter "myproject-*"
# Include forks (skipped by default)
python backup.py --include-forks
# Verbose output (useful for debugging SSH issues)
python backup.py --verbose
# Use a different config file
python backup.py --config /path/to/config.yaml
Copy config.example.yaml → config.yaml and set your usernames:
github:
username: your-github-username
gitlab:
username: your-gitlab-username
url: https://gitlab.com # change only for self-hosted GitLab
backup:
include_forks: false # default: false
include_archived: true # default: true
temp_dir: ./tmp
Tokens go in .env — never in the config file, never in logs.
| Feature | Status |
|---|---|
| Git LFS | LFS objects are not transferred (git clone --mirror skips them) |
| Organization repos | Not included in v1 — planned for v2 with --include-orgs |
| GitLab pull mirroring | Requires GitLab Premium for private repos — GitHub Actions alternative planned for v2 |