🔄 gh2gl
✨ GitHub to GitLab Mirroring CLI ✨
Seamlessly mirror your GitHub repositories to GitLab with style and ease
🌟 Features
- 🔐 Secure Authentication - Store GitHub & GitLab tokens safely with keyring
- 🚀 Bulk Mirroring - Mirror all your repositories at once
- 🎨 Beautiful UI - Rich terminal interface with progress bars and panels
- 🔒 Private Repos - Full support for private repositories
- ⚡ Smart Sync - Skip existing repos or force overwrite with
--force - 🧹 Clean Names - Automatic project name sanitization for GitLab compatibility
- 📊 Progress Tracking - Real-time statistics and detailed reporting
- 🏃 Dry Run - Preview operations without making changes
- 🛠️ Self-Hosted - Works with custom GitLab instances
📦 Installation
For Users
# Install with pipx (recommended)
pipx install gh2gl
# Or install with pip
pip install gh2gl
For Development
# Clone the repository
git clone https://github.com/viniciusccosta/gh2gl.git
cd gh2gl
# Install in development mode
pip install -e .
🚀 Quick Start
1️⃣ Setup Authentication
# Login to GitHub
gh2gl login github
# Login to GitLab
gh2gl login gitlab
2️⃣ Test Connections
# Verify API connectivity
gh2gl test
3️⃣ Mirror Repositories
# Preview what will be mirrored (dry run)
gh2gl mirror --dry-run
# Mirror all repositories
gh2gl mirror
# Force sync existing repositories
gh2gl mirror --force
📋 Commands
| Command | Description | Example |
|---|---|---|
status |
📊 Check credential configuration | gh2gl status |
test |
🧪 Test API connectivity | gh2gl test |
login github |
🔑 Setup GitHub authentication | gh2gl login github |
login gitlab |
🔑 Setup GitLab authentication | gh2gl login gitlab |
mirror |
🔄 Mirror repositories | gh2gl mirror |
⚙️ Command Options
Mirror Command Flags
--dry-run👀 - Preview operations without making changes--skip-existing⏭️ - Skip repositories that already exist on GitLab--force💪 - Overwrite existing GitLab repositories
# Examples
gh2gl mirror --dry-run # Preview only
gh2gl mirror --skip-existing # Skip existing repos
gh2gl mirror --force # Force overwrite all
🔧 Configuration
GitHub Token Setup
- Go to GitHub Settings → Developer settings → Personal access tokens
- Create a token with
repoanduserpermissions - Run
gh2gl login githuband enter your token
GitLab Token Setup
- Go to GitLab User Settings → Access Tokens
- Create a token with
api,read_repository, andwrite_repositoryscopes - Run
gh2gl login gitlaband enter your details
Custom GitLab Instance
# For self-hosted GitLab
gh2gl login gitlab
# Enter your custom GitLab URL when prompted
📸 Screenshots
Beautiful Status Display
┌─ Credential Status ─┐
│ ✨ All credentials │
│ configured! │
└─────────────────────┘
Rich Progress Tracking
🔄 Mirroring GitHub → GitLab
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 23/23 repos
┌─ Summary ─┐
│ ✅ 21 Created │
│ ⏭️ 2 Skipped │
│ ❌ 0 Errors │
└──────────────────┘
🏗️ How It Works
- 🔍 Discovery - Fetches all your GitHub repositories (public + private)
- 🧹 Sanitization - Cleans repository names for GitLab compatibility
- 🔄 Mirroring - Uses
git clone --mirrorfor complete repository copies - 📤 Upload - Pushes to GitLab with proper authentication
- 📊 Reporting - Provides detailed success/error statistics
🛡️ Security
- 🔐 Secure Storage - Tokens stored safely using system keyring
- 🚫 No Plaintext - Credentials never stored in configuration files
- 🔒 OAuth2 - Uses secure OAuth2 authentication for GitLab
- 👤 User Scoped - Only accesses repositories you have permission to
🐛 Troubleshooting
Common Issues
404 Errors
- Ensure your tokens have the correct permissions
- Verify GitLab URL is correct for self-hosted instances
Authentication Failed
- Re-run the login commands to refresh tokens
- Check token expiration dates
Repository Name Conflicts
- The tool automatically sanitizes names for GitLab compatibility
- Use
--forceto overwrite existing repositories
Debug Mode
# Run with verbose output
gh2gl mirror --dry-run # See what would happen first
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ and ☕
Happy mirroring! 🚀
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
gh2gl-0.1.0.tar.gz
(11.6 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
gh2gl-0.1.0-py3-none-any.whl
(11.9 kB
view details)
File details
Details for the file gh2gl-0.1.0.tar.gz.
File metadata
- Download URL: gh2gl-0.1.0.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.1.2 CPython/3.13.7 Darwin/24.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70de219b54c229b73e39bee7ae940ddd9cc24b75389e1a9829979414c9e71a1d
|
|
| MD5 |
7b931f8c937391b02c79684dfc86158b
|
|
| BLAKE2b-256 |
4ba3c5dce451668e3c4f72dd22bd247b2f91462eb1391d6e0ec49fe0b8995e89
|
File details
Details for the file gh2gl-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gh2gl-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.1.2 CPython/3.13.7 Darwin/24.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d6e02631f69397594e595a5fb65b318cf3c1617f26945a4de96fecf74ff2552
|
|
| MD5 |
273ba61004ab9a17e2c87903e5aaac10
|
|
| BLAKE2b-256 |
916d3ded1cb890b6b9690aef0a50f18f94faec8f9b6732aff9f585ab66736a62
|