Why Migrate From GitHub to GitLab
Migrating your source code repositories from GitHub to GitLab is a strategic decision that many development teams consider when seeking a more integrated DevOps platform, cost-effective pricing, or greater control over their development infrastructure. GitLab offers a comprehensive DevOps platform that combines source code management with continuous integration, security scanning, container registry, and project planning tools in a single application. This integrated approach eliminates the need to manage multiple disconnected services and provides a unified workflow for your entire development team.
Cost considerations often drive organizations to evaluate GitLab as an alternative. GitLab's pricing model includes generous free tiers for self-hosted deployments, and its tiered subscription structure provides flexibility for teams of all sizes. For organizations with large development teams, the cost savings from self-hosted GitLab instances can be substantial compared to per-user pricing on other platforms.
Self-hosted options make GitLab particularly attractive for organizations requiring on-premises solutions due to regulatory compliance, data sovereignty requirements, or security policies. GitLab Self-Managed gives you complete control over your infrastructure while still benefiting from regular software updates and new features. Additionally, GitLab's greater customization and configuration flexibility allows teams to tailor the platform to their specific workflows rather than adapting their processes to fit a SaaS tool's limitations.
Understanding Your Migration Options
Before beginning your migration, it's essential to understand the different GitLab deployment models available. GitLab.com provides a fully managed SaaS solution that requires no infrastructure setup, making it ideal for teams wanting to get started quickly without operational overhead. GitLab Self-Managed offers maximum control with deployment on your own infrastructure, whether on-premises or in your preferred cloud environment. GitLab Dedicated provides a single-tenant SaaS solution that balances managed convenience with complete isolation for large enterprises.
Similarly, your migration path depends on your current GitHub setup. Moving from GitHub.com to GitLab.com is the most straightforward scenario with OAuth-based imports available. Transitioning from GitHub Enterprise Server to GitLab Self-Managed requires the API-based import method but provides the same comprehensive data transfer capabilities. Each option suits different team sizes and requirements, from small teams seeking simplicity to enterprises requiring strict data governance.
Pre-Migration Planning and Prerequisites
Prerequisites for Successful Migration
Before initiating your migration from GitHub to GitLab, several prerequisites must be satisfied to ensure a successful import process. You must have access to the source GitHub project and at least the Maintainer role for the destination GitLab group to perform the import. Additionally, the GitHub import source must be enabled in your GitLab instance - this is enabled by default on GitLab.com but may require administrator configuration on Self-Managed instances.
The organization that owns the GitHub repository must not impose restrictions on OAuth app access, as this can prevent GitLab from accessing the necessary APIs to perform the import. Review your organization's OAuth policies before proceeding with migration.
GitLab's official documentation provides complete details on these requirements.
Estimating Migration Time
Migration duration depends on several factors including repository size, number of issues and pull requests, comment volume, and GitHub API rate limits. During testing, GitLab imported the Kubernetes repository, comprising approximately 80,000 pull requests, 45,000 issues, and 1.5 million comments, in approximately 76 hours. For smaller projects with fewer artifacts, the migration process typically completes much more quickly, often within minutes to a few hours.
When planning your migration timeline, consider scheduling during periods of lower development activity if possible, especially for large repositories. The import process runs in the background, so developers can continue working while migration proceeds. For enterprise migrations, account for the time needed to coordinate with team members and update downstream integrations. Our web development team can help coordinate complex migration timelines for organizations transitioning their development infrastructure.
Step-by-Step Migration Using GitHub OAuth
Method 1: Using GitHub OAuth (Recommended)
The GitHub OAuth method is the recommended approach for importing repositories from GitHub.com to GitLab. This method offers advantages over using a personal access token because the backend automatically exchanges the access token with appropriate permissions, simplifying the authentication process.
Steps to migrate using OAuth:
- In the upper-right corner of your GitLab interface, select Create new and then New project/repository
- Select Import project and then choose GitHub from the import sources
- Select Authorize with GitHub to grant necessary permissions
- GitLab will redirect you to GitHub's authorization page - grant access there
- After authorization, your GitHub repositories will be listed in the importer interface
This streamlined approach handles token exchange automatically and provides the smoothest migration experience for teams using GitHub.com. See the GitLab migration documentation for complete details on the OAuth import process.
Selecting Which Repositories to Import
After authorization, GitLab displays your GitHub repositories with filtering options to help you locate specific repositories. The default view shows repositories you own, organized by owner. Switch to the Collaborated tab for repositories where you've contributed, or the Organization tab for repositories belonging to organizations you're a member of.
By default, proposed repository namespaces in GitLab match the names in GitHub, but you can edit these before importing. Select Import next to individual repositories or Import all repositories to begin. The Status column shows real-time import progress.
Selecting Additional Items to Import
To optimize import speed, GitLab doesn't import certain items by default. Optional items include comments exceeding approximately 30,000 (requires alternative import method), Markdown attachments, and collaborators. The "Import collaborators" option is selected by default and may consume seats in your GitLab group.
| GitHub Role | GitLab Role |
|---|---|
| Read | Guest |
| Triage | Reporter |
| Write | Developer |
| Maintain | Maintainer |
| Admin | Owner |
Consider whether you want to import all collaborators or handle membership separately after migration to control seat usage effectively.
Alternative Migration Methods
Method 2: Using a GitHub Personal Access Token
For users preferring not to use OAuth or needing to import from GitHub Enterprise Server, a personal access token (PAT) provides an alternative. Generate a PAT with the repo scope (and read:org for collaborators or LFS files) from GitHub settings. In GitLab's import interface, paste the token into the "Personal access token" field and authenticate. Only classic personal access tokens are supported.
This method is useful when you want more control over authentication or need to import from self-hosted GitHub Enterprise instances. Generate your token with appropriate scopes and paste it directly into GitLab's importer to proceed with the migration.
Method 3: Using the GitLab API
The GitLab REST API provides maximum flexibility for advanced users or automated pipelines. API advantages include importing public repositories you don't own, compatibility with self-hosted GitHub Enterprise Server, and access to timeout_strategy options not available in the UI. Construct an API request with the GitHub repository URL and personal access token to initiate the import.
The API method is particularly valuable for organizations with multiple repositories requiring migration or teams wanting to automate the migration process as part of their infrastructure-as-code practices. Integrating version control migration with your CI/CD pipeline can streamline the entire transition workflow.
What Data Gets Imported
Comprehensive List of Imported Data
When migrating from GitHub to GitLab, substantial project data is automatically imported to ensure continuity of your development history and collaboration workflows.
Branches and Repository Data:
- All project branches with complete history and commit trails
- Fork branches related to open pull requests (named using pattern: GH-SHA-username/pull-request-number/fork-name/branch)
- Complete Git repository data with all commits and file history
- Git LFS objects for large file storage when configured
Issues and Pull Requests:
- Issues and pull requests with descriptions and full comment history
- Pull request reviews, comments, replies, and suggestions
- Pull request assigned reviewers and merged-by information
- Issue and pull request events and state changes
Additional Items:
- Labels, milestones, and release notes content
- Repository descriptions and wiki pages
- Branch protection rules and push rules
- Attachments for comments, issues, PRs, and releases
Branch Protection Rules Migration
GitHub branch protection rules map to GitLab configurations during import:
- "Require conversation resolution before merging" → "All threads must be resolved" project setting
- "Require a pull request before merging" → "No one" option in allowed to push and merge
- "Require signed commits" → "Reject unsigned commits" push rule
- "Allow force pushes - Everyone" → "Allowed to force push" setting
- "Require review from Code Owners" → "Require approval from code owners" setting
Note: "Require status checks to pass before merging" is NOT imported - create external status checks manually after migration.
Known Issues and Troubleshooting
GitHub API Limitations
Several known issues relate to GitHub's API limitations that affect the import process. GitHub pull request comments created before 2017 are imported in separate threads because the API lacks in_reply_to_id for that period. This creates a different discussion structure than original conversations but preserves all comment content.
Repositories with more than approximately 30,000 comments may experience incomplete imports even with the alternative import method enabled. For very large projects, plan to verify comment completeness after migration and consider manual backup of critical discussions.
Markdown attachments from GitHub Enterprise Server repositories have additional limitations. In GitLab 18.3 and earlier, these attachments are not imported. In GitLab 18.4 and later, only video and image files import, with other file types excluded.
GitLab cannot import GitHub Markdown image attachments uploaded to private repositories before May 9, 2023 due to API restrictions.
SAML SSO Complications
When importing from GitHub accounts with SAML single sign-on enabled, Markdown attachments might fail to import due to API limitations. To work around this, add the GitLab user performing the import as an Outside Collaborator to the GitHub repository to permit access during import without triggering SSO restrictions.
Reference Mapping Issues
GitLab uses # for issues and ! for merge requests, while GitHub uses # for both. During import, comment notes only link to issues (can't determine issue vs PR), and issue/PR descriptions don't create links because imported counterparts may not exist yet. Review references after migration and update manually if needed.
Verifying Import Status
Completed imports show three possible states: Complete (all entities imported successfully), Partially completed (some failed), or Failed (aborted due to critical error). Expand "Details" to see specific failed entities. Cancel pending/in-progress imports with the Cancel button. Re-import completed projects with a new name to create fresh copies if needed.
Post-Migration Configuration
Updating Remote URLs
After migration, update local git remotes to point to GitLab:
git remote -v
git remote set-url origin https://gitlab.com/your-namespace/your-project.git
Communicate new repository URLs to your team and update documentation, scripts, CI/CD configurations, and any external integrations that reference the old GitHub repository URLs.
Configuring Repository Mirroring
Repository mirroring (Premium/Ultimate) keeps your GitLab repository in sync with GitHub during transition periods. Configure the GitHub Project Integration to send pipeline status back to GitHub. Note that mirroring doesn't sync new or updated pull requests - it's designed for branch and commit synchronization only.
User Contribution Mapping
GitLab maps GitHub user contributions based on email addresses during import. Each GitHub author and assignee must have a public-facing email matching their GitLab email for automatic mapping to occur. When requirements are met, users are mapped during import, preserving attribution. If requirements aren't met, the project creator is set as author with original creator information amended into contribution text.
Optimizing Large-Scale Migrations
Increasing Import Speed on Self-Managed Instances
For large projects on GitLab Self-Managed, increase Sidekiq workers processing github_importer and github_importer_advance_stage queues. GitLab recommends at least 4 Sidekiq processes (threads = CPU cores) dedicated to import queues, optionally on separate servers. For 4 servers with 8 cores each, up to 32 objects can import in parallel.
Reducing cloning time requires improving network throughput, CPU capacity, and using high-performance SSDs for repository storage. Note that increasing Sidekiq workers doesn't reduce repository cloning time - it only speeds up the import of individual objects after cloning.
Higher API Rate Limits for Enterprise
GitHub Enterprise Cloud organizations can configure GitLab Self-Managed for higher API rate limits. Standard limit is 5,000 requests per hour; with Enterprise Cloud OAuth app, it increases to 15,000 requests per hour. Create an OAuth app owned by the Enterprise Cloud Organization, ensure GitLab has GitHub OAuth configured, and import using OAuth authentication to take advantage of increased limits.
Summary and Next Steps
Migrating from GitHub to GitLab is a well-documented process that preserves most project data while moving to a more integrated DevOps platform. Key takeaways include:
Planning: Proper pre-migration planning ensures understanding of prerequisites and realistic timeline expectations. Verify access permissions, enable import sources, and estimate duration based on repository complexity.
Methods: OAuth provides the simplest migration path for GitHub.com; API offers flexibility for enterprise and automation scenarios; personal access tokens work for GitHub Enterprise Server.
Data: Understanding what imports helps set appropriate expectations. Branches, issues, PRs, comments, and most project artifacts transfer successfully with some limitations on very large comment volumes.
Troubleshooting: Awareness of known issues allows for proactive mitigation. API limitations, SAML complications, and reference mapping differences require advance planning.
Post-Migration: Update local configurations, verify data transfer completeness, and configure additional features like mirroring as needed for your transition strategy.
For large-scale migrations, optimizing GitLab's import infrastructure significantly reduces overall migration time. Whether seeking integrated DevOps capabilities, cost advantages, or self-hosted flexibility, a successful migration establishes the foundation for improved development workflows. Our web development experts can assist with complex migration projects and help you establish optimal CI/CD practices in your new GitLab environment.