Bitbucket → GitHub
Move Bitbucket repositories to GitHub with verified Git history, LFS, identities, pull-request context, branch policy, pipelines, secrets, webhooks, deployment keys, and a mirror-based rollback.
Should you make this move?
Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.
Bitbucket
- Native Jira integration fits teams already standardized on Atlassian
- Repository-centered workflows keep code, review, and automation close together
- Its ecosystem and community surface are smaller than GitHub's
- Advanced governance and automation can become configuration-heavy
GitHub
- The largest developer ecosystem combines collaboration, automation, and public discovery
- Repository-centered workflows keep code, review, and automation close together
- Enterprise planning and governance can require several overlapping GitHub products
- Advanced governance and automation can become configuration-heavy
GitHub: The largest developer ecosystem combines collaboration, automation, and public discovery. This removes a major source-side concern: Its ecosystem and community surface are smaller than GitHub's.
What you lose: Native Jira integration fits teams already standardized on Atlassian. What you inherit: Enterprise planning and governance can require several overlapping GitHub products.
Know the shape of the move.
This timeline assumes
- Up to 100 repositories with Git, LFS, Pipelines, and common integrations.
- Bitbucket Cloud uses source-and-history migration; Bitbucket Server/Data Center may use GitHub Enterprise Importer.
- Production deploys freeze during final mirror and CI switch.
- All repositories and wikis receive offline mirror backups.
- Secrets are rotated rather than exported.
What survives the move.
“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.
| Item | Outcome | Impact | What happens | Mitigation |
|---|---|---|---|---|
| Git commits, branches, and tags | clean | critical | Mirror clone and push preserve Git history and refs. | Compare every ref tip and run fsck. |
| Git LFS objects | partial | critical | LFS requires an explicit fetch and transfer. | Compare LFS object inventories and checksums. |
| Pull requests and comments | partial | high | Cloud source-and-history paths do not carry all collaboration metadata. | Archive required history or use the supported enterprise path where eligible. |
| Issues and wiki | manual | high | They require separate migration or archival paths. | Export issues and mirror the wiki repository. |
| Users and groups | manual | critical | Workspace membership and permissions do not map automatically. | Pre-create teams and identity mapping. |
| Branch restrictions and merge checks | manual | critical | Policy semantics differ. | Rebuild rulesets, protections, reviews, and CODEOWNERS from intent. |
| Bitbucket Pipelines | partial | critical | GitHub Actions Importer can convert workflows, but manual validation remains. | Audit, dry-run, review, and exercise every release path. |
| Secrets and deployment variables | lost | critical | Secret values do not transfer safely. | Rotate into protected GitHub environments and secrets. |
| Downloads, packages, and artifacts | manual | high | Binary assets and registries have separate paths. | Inventory, copy, checksum, and test consumers. |
| Webhooks, apps, keys, and integrations | lost | critical | Installation and credential state is platform-specific. | Reauthorize or replace each integration. |
Where each thing goes.
| Source | Destination | Method | Notes |
|---|---|---|---|
| Workspace/project | Organization/team | manual | Design namespace and access first. |
| Repository | Repository | automatic | Confirm visibility and default branch. |
| Git refs | Git refs | automatic | Use mirror semantics. |
| Bitbucket user | GitHub user/team | transform | Map verified identities. |
| Branch restriction | Ruleset/branch protection | manual | Rebuild and negative-test. |
| bitbucket-pipelines.yml | .github/workflows/*.yml | transform | Use Actions Importer then review. |
| Deployment variable | Environment secret | manual | Rotate values. |
| Webhook/app | No destination | unsupported | Reinstall or replace. |
Make the move recoverable.
Create the source-of-truth backup
Preserve repositories and every operational dependency.
- Inventory repos, refs, LFS, wikis, PRs, issues, policies, pipelines, runners, secrets, artifacts, and integrations.
- Mirror clone repos and wikis, fetch all LFS, and run fsck.
- Export collaboration counts and required metadata.
- Checksum assets and record secret names/consumers.
- Test one restore.
Proof to capture: A repository manifest reconciles refs, objects, metadata, policy, CI, assets, and integrations.
CI conversion
Create reviewed GitHub Actions workflows.
- Audit pipelines.
- Run dry-run conversion.
- Review permissions and test build, release, deploy, and rollback.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
Policy and identity map
Recreate least privilege and merge controls.
- Map users and teams.
- Map restrictions to rulesets.
- Run forbidden-action tests.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
The things most likely to hurt.
These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.
Repositories diverge
A Bitbucket ref advances after final mirror.
- Consequence
- Code and releases split.
- Mitigation
- Freeze writes and lock the source.
Stop if: Any uncaptured source ref advances.
CI permissions broaden
Untrusted workflows read protected secrets.
- Consequence
- Infrastructure compromise.
- Mitigation
- Minimize token permissions and protect environments.
Stop if: A pull request can access production credentials.
Policy disappears
Forbidden push or merge succeeds.
- Consequence
- Unreviewed code reaches production.
- Mitigation
- Run negative role tests.
Stop if: Any required control fails.
Do the work in this order.
- Days 1–4 · inventory
Inventory
16–24 hours active4 days elapsedOwner review waiting- Inventory data and dependencies.
- Design organizations, teams, policy, and waves.
Depends on: Admins
Stop / go checkpointBack up?
Go when: Every repo and production dependency has an owner.
Stop when: Critical CI or secret consumer is unknown.
- Days 5–7 · backup
Mirrors
10–18 hours active3 days elapsedClone and LFS transfer waiting- Create mirrors and metadata archives.
- Validate restore.
Depends on: Scope
Stop / go checkpointPilot?
Go when: Refs, LFS, wiki, and assets reconcile.
Stop when: Any critical object is missing.
- Days 8–12 · pilot
Pilot
15–24 hours active5 days elapsedCI runs waiting- Migrate representative repos.
- Translate CI and policies.
- Test release and rollback.
Depends on: Backup
Stop / go checkpointWaves?
Go when: All repo archetypes pass.
Stop when: Data, policy, or CI fails.
- Days 13–22 · waves
Migration waves
15–32 hours active6–10 days elapsedImports and reviews waiting- Migrate by dependency.
- Reconcile each repo and integration.
Depends on: Pilot
Stop / go checkpointCut over?
Go when: Every repo is complete or excepted.
Stop when: Any critical variance remains.
- Days 23–30 · cutover
Final mirror and observation
4–12 hours active5–8 days elapsedNormal workflows waiting- Freeze and mirror final refs.
- Switch CI, remotes, webhooks, and deploys.
- Observe releases.
Depends on: Waves
Stop / go checkpointClose rollback?
Go when: Two release paths and all checks pass.
Stop when: A critical source write or integration remains.
Cut over with a way back.
Cutover
Make GitHub the only writable code and CI control plane.
- Freeze Bitbucket writes and deploys.
- Mirror final Git and LFS refs.
- Rotate secrets and switch CI.
- Switch remotes, webhooks, apps, and deployment keys.
- Run policy and release tests.
- Lock Bitbucket.
Proof to capture: Refs match and GitHub alone completes a protected release and rollback.
Rollback
Restore Bitbucket without losing GitHub commits.
- Freeze GitHub.
- Mirror new refs to quarantine.
- Push approved refs to Bitbucket.
- Restore pipelines, secrets, policy, and integrations.
- Run release tests.
Proof to capture: Bitbucket contains approved refs and completes the protected release path.
- Missing refs or LFS
- Policy bypass
- Production pipeline failure
- Access exposure
- Critical integration failure
Prove the migration worked.
Every blocking check must pass. Capture the evidence before cleanup begins.
| Pass | ID | Check | Method | Expected result | Evidence |
|---|---|---|---|---|---|
V-01Blocking | Refs | Compare all tips and fsck. | Exact parity. | Ref diff. | |
V-02Blocking | Objects | Compare inventories and downloads. | Every pointer resolves. | LFS report. | |
V-03Blocking | PRs, issues, and wiki | Reconcile counts or archive disposition. | 100% accounted for. | Metadata report. | |
V-04Blocking | Membership | Test role accounts. | Least privilege. | Access matrix. | |
V-05Blocking | Merge controls | Attempt forbidden actions. | All are blocked. | Negative tests. | |
V-06Blocking | Release path | Run build through rollback. | Approved result. | Workflow runs. | |
V-07Blocking | Binary availability | Compare checksums. | Critical assets match. | Asset manifest. | |
V-08Blocking | Event delivery | Trigger each integration. | One GitHub event. | Delivery log. |
Remove the scaffolding safely.
Safe after: Two successful releases and 30 stable days.
- Archive mirrors and evidence.
- Revoke Bitbucket tokens and keys.
- Remove old runners and webhooks.
- Keep Bitbucket read-only through retention.
- Update development documentation.
- Schedule quarterly access, policy, secret, and restore reviews.
Built to be reviewed.
Tested 2026-07-19. Next scheduled review: 2026-10-19.
- GitHub: migration paths to GitHubAccessed 2026-07-19
- GitHub: migrate Bitbucket PipelinesAccessed 2026-07-19
- GitHub: import external Git repositoryAccessed 2026-07-19