🔄 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! 🚀
Metadata
Release files for gh2gl 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| gh2gl-0.1.0.tar.gz | 11.6 kB | Without provenance | Details for gh2gl-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| gh2gl-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for gh2gl-0.1.0-py3-none-any.whl |
Total release size: 23.6 kB
Release files / gh2gl-0.1.0.tar.gz
| Download URL | gh2gl-0.1.0.tar.gz |
|---|---|
| Size | 11.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
70de219b54c229b73e39bee7ae940ddd9cc24b75389e1a9829979414c9e71a1d
|
|
BLAKE2b-256 checksum How to use checksums |
4ba3c5dce451668e3c4f72dd22bd247b2f91462eb1391d6e0ec49fe0b8995e89
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.2 CPython/3.13.7 Darwin/24.6.0
|
Release files / gh2gl-0.1.0-py3-none-any.whl
| Download URL | gh2gl-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4d6e02631f69397594e595a5fb65b318cf3c1617f26945a4de96fecf74ff2552
|
|
BLAKE2b-256 checksum How to use checksums |
916d3ded1cb890b6b9690aef0a50f18f94faec8f9b6732aff9f585ab66736a62
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.2 CPython/3.13.7 Darwin/24.6.0
|
Security for gh2gl 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.