← All playbooks
Development migration

GitHub → GitLab

Move repositories and collaboration history from GitHub to GitLab with explicit handling for identities, LFS, attachments, CI/CD, protections, integrations, secrets, package registries, cutover, and mirror-based rollback.

Typical timeline15–30 business days70–130 hours active work
Statusneeds review
Source testedGitHub backup guidance reviewed 2026-07-19
Destination testedGitLab GitHub importer guidance reviewed 2026-07-19
Last reviewed2026-07-19
Sources4
Before you migrate

Should you make this move?

Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.

Current platform

GitHub

Reasons to stay
  • The largest developer ecosystem combines collaboration, automation, and public discovery
  • Repository-centered workflows keep code, review, and automation close together
Reasons to leave
  • Enterprise planning and governance can require several overlapping GitHub products
  • Advanced governance and automation can become configuration-heavy
New platform

GitLab

What gets better
  • A comprehensive DevSecOps platform offers deep CI/CD and self-hosting options
  • Repository-centered workflows keep code, review, and automation close together
What gets worse
  • Breadth, upgrades, and administration can be heavy for smaller teams
  • Advanced governance and automation can become configuration-heavy
Best of the move

GitLab: A comprehensive DevSecOps platform offers deep CI/CD and self-hosting options. This removes a major source-side concern: Enterprise planning and governance can require several overlapping GitHub products.

Worst of the move

What you lose: The largest developer ecosystem combines collaboration, automation, and public discovery. What you inherit: Breadth, upgrades, and administration can be heavy for smaller teams.

01At a glance

Know the shape of the move.

Transfer outcome13 features audited
Transfer outcome distributionClean transfer: 1, Partial transfer: 7, Manual rebuild: 3, Not transferred: 2.
Clean1
Partial7
Manual3
Lost2
Mapping route11 of 12 fields have a destination path

This timeline assumes

  • Profile: one GitHub organization with at most 100 repositories, 500 users, 30,000 comments per project, and no GitHub Enterprise Server.
  • You control organization settings, GitLab top-level groups, DNS, CI credentials, registries, OAuth applications, and production deployment targets.
  • Every repository receives a mirror backup and its wiki, LFS objects, releases, packages, secrets, environments, and integrations are inventoried separately.
  • GitLab usernames and emails are mapped before import; unidentified authors are accepted only with an explicit attribution exception.
  • Production deploys are frozen while the final Git mirror, CI switch, and webhook cutover occur.
02Loss matrix

What survives the move.

“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.

ItemOutcomeImpactWhat happensMitigation
Git branches, tags, commits, and full revision historycleancriticalA mirror clone and push preserve Git refs and object history when all refs are included.Back up with --mirror, run fsck, compare refs and commit tips, and include submodules separately.
Issues and pull requestspartialcriticalThe GitLab importer moves issues and pull requests into GitLab concepts, but state, review semantics, references, and edge cases are not identical.Pilot repositories with complex reviews, cross-links, draft PRs, and merged branches.
Comments and review commentspartialhighLarge projects with roughly 30,000 or more comments can exceed the recommended importer path; attribution also depends on user mapping.Use GitLab's documented alternate method for large projects and reconcile counts by type.
Markdown attachmentspartialhighAttachments require the relevant importer option; otherwise links in migrated Markdown can break.Enable attachment import, scan migrated Markdown URLs, and preserve a source archive.
Git LFS objectspartialcriticalGit refs can migrate while LFS binaries are missing unless explicitly fetched and transferred.Fetch all LFS objects, compare object inventories, and download representative binaries.
Users and organization structuremanualcriticalThe GitHub importer does not create GitLab groups from organizations and imports only supported direct collaborators; outside collaborators can be omitted.Create groups, subgroups, users, and identity mappings first, then audit effective membership.
Branch protection and rulesetspartialcriticalSome branch protection can map, but GitHub rulesets, status-check requirements, bypass actors, and custom roles are not equivalent.Rebuild protected branches, approval rules, push rules, CODEOWNERS, and merge checks from an approved policy matrix.
GitHub Actions workflowsmanualcriticalWorkflow YAML, runners, environments, approvals, OIDC trust, caches, and marketplace actions do not become GitLab CI behavior automatically.Translate to .gitlab-ci.yml, replace actions, use GitLab variables and identities, and run release-path tests.
Secrets, variables, and environmentslostcriticalSecret values are intentionally not exportable and environment rules differ.Create a secret inventory without values, rotate credentials, and enter them through approved GitLab secret controls.
Packages, releases, and artifactspartialhighRelease metadata, binary assets, container images, packages, Actions artifacts, and caches have separate migration paths and retention rules.Inventory each registry and artifact class, then copy and verify with native clients.
Wikis and GitHub PagesmanualhighWikis are separate Git repositories and Pages build/deployment settings are platform-specific.Mirror wiki repositories and rebuild Pages publishing and domains in GitLab.
Webhooks, apps, bots, and integrationslostcriticalInstallation IDs, tokens, webhook secrets, checks, project boards, Dependabot, and external automation do not transfer as working integrations.Reauthorize or replace each integration and test delivery before disabling GitHub.
Fork relationshipspartialhighRepository content can transfer while fork-network relationships may not persist across migration methods.Document required fork topology and test upstream/downstream contribution flows.
03Field and feature mapping

Where each thing goes.

SourceDestinationMethodNotes
GitHub organizationGitLab top-level groupmanualCreate group and subgroup hierarchy before project import.
RepositoryGitLab projectautomaticConfirm visibility, default branch, namespace, and path.
Git refsGit refsautomaticUse mirror semantics and compare every ref tip.
Pull requestMerge requestautomaticReview and merge semantics still require scenario validation.
Issue and labelIssue and labelautomaticReconcile counts, states, assignees, milestones, and cross-references.
GitHub user/emailGitLab user/emailtransformPre-create an identity map to preserve attribution.
Branch protection/rulesetProtected branch and approval/merge rulesmanualRecreate policy from intent; status checks are not imported as an equivalent rule.
.github/workflows/*.yml.gitlab-ci.yml and CI includesmanualTranslate jobs, matrices, permissions, environments, caching, and release steps.
Actions secretGitLab masked/protected CI/CD variable or external secretmanualRotate; secret values cannot be exported safely.
GitHub release and assetGitLab release and package/generic assettransformCopy binaries and verify checksums.
GitHub wikiGitLab wikimanualMirror the separate .wiki.git repository.
GitHub App/webhookNo destinationunsupportedInstall a GitLab-native integration or update the external service.
04Before you begin

Make the move recoverable.

Backup procedure

Create the source-of-truth backup

Preserve every repository and the operational metadata required to reconstruct development and release workflows.

  1. Inventory repositories, visibility, archived/fork/template status, refs, LFS, submodules, wikis, Pages, issues, PRs, releases, packages, Actions, environments, rules, teams, apps, webhooks, deploy keys, and production dependencies.
  2. Create a --mirror clone of every repository and wiki, fetch all LFS objects, run git fsck, and record ref tips.
  3. Export organization/repository metadata and issue/PR counts through approved GitHub APIs or enterprise migration exports.
  4. Download required release assets and package/container artifacts with checksums.
  5. Record secret names and consumers without exporting values; plan rotation.

Proof to capture: A repository-by-repository manifest contains mirror hashes, ref and LFS counts, collaboration counts, assets, policies, integration owners, and restore instructions.

Transformation · GitHub/GitLab API export plus mapping table

Identity and namespace map

Preserve attribution and least-privilege access.

  1. Map organization, teams, users, bots, externals, and emails.
  2. Create GitLab groups and users before import.
  3. List every unmapped identity as a blocking exception.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · GitLab CI lint and isolated runners

CI/CD translation

Rebuild tested pipelines rather than copying inert workflow files.

  1. Map triggers, jobs, services, permissions, caches, artifacts, environments, and approvals.
  2. Rotate variables and update OIDC/cloud trust.
  3. Run build, test, preview, production, and rollback paths.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · Branch/ruleset policy matrix

Policy reconstruction

Recreate repository protection from its security intent.

  1. Inventory GitHub rulesets, protections, CODEOWNERS, status checks, and bypass actors.
  2. Map to protected branches, approvals, push rules, and merge checks.
  3. Test allowed and forbidden actions with role accounts.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

05Handle with care

The things most likely to hurt.

These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.

Cutover

Developers push to both hosts

criticalpossible likelihood

New commits appear on GitHub after the final mirror starts.

Consequence
Histories diverge and releases use inconsistent source.
Mitigation
Freeze pushes, archive or lock GitHub, and advertise one canonical remote.

Stop if: Any uncaptured GitHub ref advances after the freeze.

CI/CD

CI reaches production with broader credentials

criticalpossible likelihood

Translated jobs use long-lived or unprotected variables.

Consequence
Source or infrastructure compromise.
Mitigation
Rotate secrets, minimize job tokens, protect environments, and test untrusted merge requests.

Stop if: A non-protected pipeline can read a production credential.

Policy

Required merge controls disappear

criticalpossible likelihood

A role account can merge without required approval or checks.

Consequence
Unreviewed code reaches protected branches.
Mitigation
Run explicit negative policy tests.

Stop if: Any forbidden push or merge succeeds.

Data

LFS or release binaries are missing

criticalpossible likelihood

Pointers resolve but binaries fail to download.

Consequence
Builds, releases, or historical checkouts break.
Mitigation
Compare object inventories and checksums.

Stop if: Any production-required binary is unavailable.

Import

Importer rate limits or partial states are ignored

highlikely likelihood

GitLab marks a project partial or reports failed relation types.

Consequence
The project looks available while metadata is incomplete.
Mitigation
Save status details, retry controlled failures, and reconcile all object counts.

Stop if: Any project remains partial without an accepted exception.

06Precise timeline

Do the work in this order.

Estimate forOne organization with up to 100 repositories and 500 users
Total elapsed15–30 business days
Active work70–130 hours
BufferAdd 1–3 weeks for complex Actions pipelines, large comment histories, registries, compliance approval, or external integrations.
01
Days 1–4Inventory and target design4 days
02
Days 5–7Mirrors and evidence3 days
03
Days 8–11Pilot representative projects4 days
04
Days 12–20Import in waves5–9 days
05
Days 21–23Final mirror and control-plane switch1–3 days
06
Days 24–30Read-only observation5–7 days
  1. Days 1–4 · inventory

    Inventory and target design

    18–28 hours active4 days elapsedOwner and security review waiting
    • Inventory repositories, identities, collaboration data, policies, CI/CD, artifacts, and integrations.
    • Create namespace, identity, retention, and freeze plans.

    Depends on: GitHub organization owner and GitLab owner access

    Stop / go checkpoint

    Approve migration waves?

    Go when: Every repository and operational dependency has an owner and method.

    Stop when: A production pipeline, secret consumer, or compliance requirement is unknown.

  2. Days 5–7 · backup

    Mirrors and evidence

    12–20 hours active3 days elapsedClone, LFS, and artifact transfer waiting
    • Create and validate Git, wiki, LFS, asset, and metadata backups.
    • Record source ref and object counts.

    Depends on: Approved inventory

    Stop / go checkpoint

    Can every repository be restored?

    Go when: Mirrors pass fsck and all critical binaries and metadata are accounted for.

    Stop when: A required ref, LFS object, release asset, or wiki is absent.

  3. Days 8–11 · pilot

    Pilot representative projects

    14–22 hours active4 days elapsedImporter and CI runs waiting
    • Import simple, large-history, LFS, release, and complex-CI projects.
    • Validate attribution, policies, pipeline permissions, artifacts, and integrations.

    Depends on: GitLab groups and users, Backups

    Stop / go checkpoint

    Approve bulk import?

    Go when: All critical project archetypes pass data, security, CI, and release checks.

    Stop when: Attribution, protections, binaries, or production rollback cannot be proven.

  4. Days 12–20 · waves

    Import in waves

    18–35 hours active5–9 days elapsedGitHub API limits and import queues waiting
    • Import projects by dependency wave.
    • Reconcile each project and translate CI, policies, assets, and webhooks before advancing.

    Depends on: Approved pilot

    Stop / go checkpoint

    Schedule final freeze?

    Go when: Every project is complete or has an approved exception and release paths pass.

    Stop when: Any importer partial state or critical CI failure remains.

  5. Days 21–23 · cutover

    Final mirror and control-plane switch

    5–9 hours active1–3 days elapsedFinal CI and webhook runs waiting
    • Freeze GitHub pushes and deploys.
    • Mirror final refs and LFS, rotate secrets, switch webhooks/remotes, then run staged pipelines.

    Depends on: Approved waves, Maintenance window

    Stop / go checkpoint

    Make GitLab canonical?

    Go when: Refs match, policies reject forbidden actions, and production release/rollback pass.

    Stop when: Any source ref advances or production controls differ from policy.

  6. Days 24–30 · observe

    Read-only observation

    3–16 hours active5–7 days elapsedDeveloper feedback and scheduled jobs waiting
    • Keep GitHub read-only and monitor clones, webhooks, pipelines, releases, bots, and developer workflows.
    • Complete verification and owner sign-off.

    Depends on: Successful cutover

    Stop / go checkpoint

    Close rollback window?

    Go when: Blocking checks pass across normal and scheduled workflows.

    Stop when: A critical integration still writes to GitHub or a GitLab workflow is unsafe.

07The point of change

Cut over with a way back.

Go live

Cutover

Make GitLab the only writable source and CI/CD control plane while preserving a final verified GitHub snapshot.

Recommended window: A low-release Friday with the final mirror after code freeze and a staffed verification period before Monday.

  1. Freeze GitHub merges, pushes, releases, package publication, and deploys.
  2. Record final refs, mirror Git and LFS, and reconcile object counts.
  3. Rotate credentials and configure protected GitLab variables, deploy keys, runners, and environments.
  4. Switch remotes, webhooks, apps, registries, badges, documentation, and deployment integrations.
  5. Run protected-branch negative tests and staged build, test, release, deploy, and rollback pipelines.
  6. Archive or lock GitHub repositories and show the canonical GitLab URL.

Proof to capture: Final refs match, policy tests pass, all critical binaries resolve, and one complete production release and rollback simulation succeeds from GitLab.

Return to safety

Rollback

Restore GitHub as canonical without discarding GitLab commits or security changes.

Deadline: Within 72 hours and before multiple independent releases or package publications occur on GitLab.

  1. Freeze GitLab pushes, pipelines, releases, and package publication.
  2. Mirror new GitLab refs and LFS objects into a quarantine backup.
  3. Review and push approved new refs back to GitHub.
  4. Restore rotated GitHub secrets, integrations, branch rules, remotes, and deployment controls.
  5. Run GitHub policy and release-path tests before reopening writes.

Proof to capture: GitHub contains all approved refs, rejects forbidden actions, and completes the tested release path while GitLab is read-only.

Rollback immediately when
  • Missing refs, LFS objects, or critical assets
  • Required policy bypass is possible
  • Production pipeline or rollback fails
  • Identity or permission mapping exposes restricted projects
  • Critical integration cannot operate against GitLab
08Verification report

Prove the migration worked.

Every blocking check must pass. Capture the evidence before cleanup begins.

0%
Interactive report preview0 / 8 checks passed
PassIDCheckMethodExpected resultEvidence
V-01BlockingRefs and objectsCompare all branch/tag/ref tips, run fsck, and sample historical checkouts.Exact ref parity and no corrupt or missing object.Ref diff and fsck logs.
V-02BlockingLarge-file availabilityCompare LFS inventories and download production-critical objects.Every required pointer resolves to the correct checksum.LFS object report.
V-03BlockingIssues, merge requests, comments, and attributionReconcile counts and inspect representative complex histories.Every object is imported or listed as an approved exception; authorship is explained.Object-count reconciliation.
V-04BlockingMembership and visibilityTest internal, external, bot, and unauthorized role accounts.Least-privilege access matches the approved matrix.Role test matrix.
V-05BlockingProtected workflowAttempt forbidden push, merge, approval, and secret-access scenarios.Every forbidden action fails and required checks block correctly.Negative-test log.
V-06BlockingRelease pathRun build, test, artifact, preview, protected deploy, and rollback scenarios.Outputs and approvals match the accepted pipeline specification.Pipeline URLs and deployment evidence.
V-07BlockingReleases, packages, containers, and wikiReconcile inventories and verify representative checksums and clones.Every retained artifact class is usable from its destination.Artifact manifest.
V-08BlockingExternal eventsTrigger each webhook, bot, scanner, notification, Pages build, and deployment integration.One successful destination event and no production write to GitHub.Integration delivery log.
09Post-migration cleanup

Remove the scaffolding safely.

Safe after: At least two normal release cycles, all scheduled workflows, and 30 days without a rollback trigger.

  1. Preserve mirrors, LFS, assets, manifests, importer logs, identity mappings, policy tests, and verification evidence.
  2. Revoke GitHub PATs, deploy keys, app installations, webhooks, runner tokens, and machine credentials no longer required.
  3. Delete temporary migration tokens and staging mirrors from unsecured machines.
  4. Retain GitHub repositories archived for the approved compliance window before any deletion decision.
  5. Update onboarding, incident response, backup, release, and ownership documentation.
  6. Schedule quarterly restore, access, policy, integration, and dormant-secret reviews.
Sources and maintenance

Built to be reviewed.

Tested 2026-07-19. Next scheduled review: 2026-10-19.

  1. GitLab: migrate from GitHubAccessed 2026-07-19
  2. GitLab: project import and exportAccessed 2026-07-19
  3. GitHub: backing up a repositoryAccessed 2026-07-19
  4. GitHub: organization migration exportsAccessed 2026-07-19