What a Bitbucket to Gitea migration involves and who runs it
If your Bitbucket renewal, licensing change or residency requirement has forced a decision, the short answer is this: repositories and Git history move cleanly, but pull requests, comments and permissions need separate work. A clone or mirror carries commits, branches and tags from Bitbucket Cloud or Bitbucket Data Center into Gitea without loss of history. Gitea's documented migration paths do not include a Bitbucket importer, so the review record, issue data and access model have to be planned, exported and rebuilt on purpose. Starting points differ. Bitbucket Cloud is hosted by Atlassian and its API and export options are governed by its own rate limits, while Bitbucket Data Center runs on infrastructure you already operate, which changes what you can copy directly from the server. In both cases, the destination is software your organization installs, operates, upgrades and backs up itself.
The team usually includes platform or DevOps engineers who build the Gitea instance, storage and backups, a Bitbucket administrator who knows the workspace or project structure, branch permission rules and linked services, and a security or compliance owner who signs off on identity, audit logging and retention decisions. Developers and team leads matter too, because they decide which open pull requests and comment threads must survive the move and which can be closed or archived in Bitbucket. Effort is driven less by the Git data than by the number of repositories, how much review history teams need to keep, how many Pipelines jobs and Jira links depend on the old setup, and how much permission logic lives in Bitbucket's configuration. Ask your Bitbucket administrator to inventory these before anyone estimates timelines. Any quote should separate the one-time work of migration and cutover from the recurring work of running and patching Gitea afterward.
Which Bitbucket capabilities map to Gitea and which need rework
This table maps the Bitbucket capabilities most teams use to their Gitea equivalents and labels each as clean, needs rework or gap. Read it as a checklist for your own environment, since Gitea's migration tooling does not include a Bitbucket importer and each feature should be confirmed against your Bitbucket edition and your Gitea version. The main takeaway is that Git content moves cleanly, while pull requests, Pipelines and Jira links need a deliberate plan.
| Bitbucket capability | Gitea equivalent | Status | What to confirm or do |
|---|---|---|---|
| Repositories and branches | Git repositories and branches | Clean | Mirror every branch and tag with a Git clone or mirror, then verify commit counts and default branch. |
| Git LFS objects | Gitea LFS storage | Needs rework | Confirm LFS is enabled on the Gitea instance, then push LFS objects and check that large files download on a fresh clone. |
| Pull requests and history | Gitea pull requests | Gap | Gitea has no Bitbucket importer, so pull request records are not carried over. Export them through the Bitbucket API into an archive if you need them. |
| Inline review comments | Gitea review comments | Gap | Comments attached to Bitbucket pull requests do not arrive with the Git history. Decide whether an archive is enough for audit needs. |
| Branch permissions | Branch protection rules | Needs rework | Recreate each rule by hand, including required approvals and push restrictions, then test each rule with a non-admin account. |
| Pipelines (CI/CD) | Gitea Actions | Needs rework | Gitea Actions is designed to be compatible with GitHub Actions, so rewrite bitbucket-pipelines.yml rather than copying it. Confirm each step, runner and secret in your own environment. |
| Pipeline variables | Repository and organization secrets | Gap | Pipelines variables cannot be read back from Bitbucket, so re-enter each secret from its source system. |
| Issues | Gitea issues, labels and milestones | Needs rework | No importer maps Bitbucket issues, so export them and recreate or archive them, then confirm the labels and milestones you need. |
| Wiki | Gitea wiki | Needs rework | Clone the Bitbucket wiki repository as Git and push it to the Gitea wiki, then check internal links. |
| Jira links and webhooks | Gitea webhooks and an external integration | Gap | Gitea has no built-in Jira link. Identify each Jira integration and webhook, then confirm which replacement your team will use. |
What data moves, by which documented path, and what to rebuild
Bitbucket data does not move as one bundle. Git history and LFS objects travel by clone or mirror, while pull requests, comments, issues and wiki content need a separate export path. Identities, integrations and pipeline secrets are rebuilt in Gitea rather than copied across.
Git history and LFS objects
Clone each repository with its full history and fetch its LFS objects, then push everything to the Gitea target. Gitea's migration form can pull a repository from a supported source, but Bitbucket is not one of them, so a mirror push is the documented route for Bitbucket content. Check that every LFS object is present on the target before you retire the source, because a missing object shows up only when someone checks out an old commit.
Pull requests and review comments
Gitea has no Bitbucket importer, so pull requests, inline review comments and their approvals do not arrive with the code. Plan an export through the Bitbucket API and decide which history must be kept as searchable records, such as a document or archive, and which can stay in Bitbucket until the read-only window closes. Confirm how your Bitbucket plan's API quota affects a full export, since most resources allow 1,000 requests per hour.
Issues and wiki content
Issues and wiki pages follow the same rule: no direct importer covers Bitbucket to Gitea, so they need their own export and a target location in Gitea. Map issue labels, assignees and milestones to Gitea equivalents by hand or with a script, and note which wiki links point at repository paths that will change. Agree with the owners which open issues are migrated and which are closed in place.
Users, SSH keys and access
Gitea accounts, organizations and team memberships are created in the new instance, and user SSH keys and personal access tokens are not carried over from Bitbucket. Ask each developer to add their SSH public key again, and recreate repository and team access from an access list you export first. Plan this with your identity provider, because the new forge's sign-in method determines how accounts are onboarded.
Webhooks, deploy keys and branch rules
Repository webhooks, deploy keys and branch permission rules are configuration, not Git data, so none of them moves with the clone. Recreate each webhook with its target URL and secret, add every deploy key to the matching Gitea repository, and rebuild branch protection rules, required reviewers and merge restrictions. Test each rule with a branch push that should fail before you rely on it.
Pipelines variables and Jira links
Bitbucket Pipelines variables, especially secured ones, cannot be read back through the API, so each secret must be re-entered from the source of truth in your secrets store. Pipeline definitions in bitbucket-pipelines.yml must be rewritten for Gitea Actions or another runner, and Jira smart commit and branch links need a new integration. List each variable, its owner and its consumer before cutover.
Migration sequence from inventory to decommissioning
This sequence moves Bitbucket repositories to self-hosted Gitea in controlled phases, so each stage produces evidence the team can check before the next one starts. Repository history and LFS objects move first, while pull request history, permissions and pipelines get their own tracks. The end state is a working Gitea instance and a read-only archive of the Bitbucket data.
Inventory repositories, LFS, permissions and integrations
The platform owner lists every repository in the Bitbucket Cloud or Data Center workspace, marking which use Git LFS, which are archived, and which have forks or large histories. The team also records project and branch permissions, default branches, webhooks, deploy keys, Pipelines configurations, and links to Jira issues. Repository sizes are checked against Bitbucket Cloud's 4 GB repository limit before any pilot repository is chosen, and any repository near that limit is flagged for separate handling. The step is complete when the inventory is signed off by the code owners and every repository has a named migration path.
Run a pilot with selected repositories
The team selects a small set of repositories with different profiles, including at least one that uses LFS, one with a long history and one with an active branch policy. Each is mirrored into a test Gitea instance with
git clone --mirrorand LFS objects are fetched and pushed separately. Engineers confirm commit counts, tags, branch heads and LFS file checksums match the source, and they rebuild one branch protection rule by hand. Pull requests and comments are exported through the Bitbucket API within its rate limits so the team can judge how much history is worth carrying forward. The pilot is done when the checks pass and the team has a written list of gaps.Re-create permissions and CI in Gitea
Using the inventory, the team maps Bitbucket projects and groups to Gitea organizations and teams, then recreates branch protection, required reviewers and default branch settings. Pipelines jobs are rewritten as Gitea Actions workflows, which are designed to be compatible with GitHub Actions, and each workflow is run against a pilot branch. Secrets are re-entered in Gitea from the owning teams' records, since Pipelines variables cannot be read back from Bitbucket. Webhooks to Jira and other tools are replaced with equivalents that the integration owners test. The step closes when a sample of users confirms that access matches the approved matrix and each pilot pipeline passes.
Run both systems in parallel
Bitbucket stays available for reads and writes while Gitea receives scheduled mirror syncs of all in-scope repositories, including LFS objects. Teams begin opening new pull requests in Gitea for pilot repositories and keep the old Bitbucket review history as a reference. Sync logs, failed mirror jobs and drift between branch heads are reviewed on a fixed schedule, and any repository with divergent history is fixed at the source. The team also tracks which pull request discussions will be archived rather than migrated. The parallel run ends when sync reports are clean across the full set and the teams agree that Gitea is the working system of record.
Cut over during a freeze window
The team announces a freeze window in which Bitbucket receives no new pushes, then runs one final mirror sync and compares refs and LFS checksums against the source. Local clones, CI runners, deployment scripts and documentation are updated to point to the Gitea remote URLs, and DNS or internal redirects are changed if the team uses a stable hostname. Each repository is checked by a build and a test run in its new location before the freeze ends. Developers are asked to re-clone or update their remotes, and the team records any issues in a cutover log. Cutover is complete when all in-scope repositories build from Gitea and no active process still writes to Bitbucket.
Decommission Bitbucket with retained archives
Once the cutover log is closed, Bitbucket repositories are set to read-only where the plan allows, and the team exports the final archive set, including repository bundles, LFS objects, the pull request and comment export, and the permission inventory. The archive is stored in an access-controlled location with a named owner and a retention period set by the organization's records policy, which the team confirms with its compliance lead. Bitbucket integrations, webhooks and API tokens are revoked, and seat or workspace subscriptions are reviewed with the commercial owner. The step is complete when the archive is verified by restoring one repository from it and the decommissioning record is approved.
How the pull request history and branch rules get re-created
Git history can be mirrored with full fidelity, but pull request records cannot be imported as live Gitea pull requests because Gitea's migration code has no Bitbucket importer. Plan for two separate tracks. The first is the Git track: mirror every branch, tag and LFS object so commit hashes and file history stay identical. The second is the review record track: export pull requests, reviews and comments through the Bitbucket API, then archive them read-only in a file store, or convert the important threads into Gitea issues or repository documentation. Decide which open pull requests must be finished in Gitea before cutover, and close or re-open those by hand, because a reviewer's approval does not carry over.
Branch protection and team permissions are re-created in Gitea by hand or by script, using the export as your source of truth. Record every Bitbucket branch permission rule, including the branch pattern, required approvals, merge checks and who may push, then map each one to a Gitea branch protection rule on the matching repository. Map Bitbucket groups and project permissions to Gitea organizations, teams and repository access levels, and confirm which accounts hold admin rights. Gitea Enterprise adds organization-level branch protection inheritance, so a single policy can cover many repositories, along with SAML 2.0 support, audit logging and mandatory two-factor authentication for teams that need those controls. Confirm whether your edition provides them before you design the policy.
Do not assume that a rule you configured behaves the same way in your Gitea version. Create a test repository on the same release you will run in production, set up a protected branch, and try direct pushes, forced pushes, merges without the required approvals and merges by a user who lacks write access. Compare each result with what Bitbucket did before cutover. Check the release notes for the version you install, since branch protection behavior and API fields can change between releases. Record the test results as part of your migration evidence.
How the migration differs for Cloud and Data Center starting points
Bitbucket Cloud gives you no database or server access, so every export runs through Git and the REST API. Git history moves with a clone or mirror, but pull requests, comments and issues must be pulled through the API, and that API is rate limited. Bitbucket Cloud allows 1,000 requests per hour for most API resources, according to Atlassian's documentation, so a large pull request history can take many hours of paced requests to export. Plan the export by workspace and project rather than in one run.
- API pacing: Script the export to back off when limits are hit, and schedule the largest projects first so retries do not block the cutover.
- Workspace and seat structure: Confirm which workspaces, projects and users own each repository, because permissions and ownership do not carry over as Bitbucket objects.
- Repository size: Bitbucket Cloud enforces a 4 GB repository limit and a 1 GB total storage limit on Free workspaces, so check sizes before cloning.
- Pipelines variables: Secured variables cannot be read back through the API, so record them from the owners before the workspace is closed.
- Access window: Keep the Cloud workspace readable until the Gitea instance has been verified.
Confirm current limits, export tooling and any Cloud contract terms with Atlassian before you set the cutover date.
Bitbucket Data Center runs on your own servers, so you control the database, the filesystem and the backup routines. That gives you direct options that Cloud does not offer: you can read repositories from the server storage, take a consistent backup of the instance, and query its database for an inventory of projects, repositories and pull requests. Data Center is also part of Atlassian's roadmap, since its journey-to-cloud page states that Bitbucket Data Center will continue beyond 2029 and that existing customers gain a Bitbucket Hybrid License covering Data Center and Cloud. Confirm the exact license terms with Atlassian before you rely on them.
- Direct data access: Export repositories from the server storage and use the database for a complete inventory, which avoids the API rate limits used in Cloud.
- Backups as a safety net: Keep a full instance backup until Gitea has passed verification, since it preserves permissions and pull request data that a plain Git mirror does not.
- Hybrid License context: Ask Atlassian whether your current license qualifies for the Hybrid License and what it allows during a phased move.
- Server access: Your own administrators must have the access needed to run exports on the host, so agree roles and change windows in advance.
- Extension data: Check which marketplace apps store data in Bitbucket, since their data formats differ from core objects.
Ask Atlassian in writing which Data Center version and support window applies to your instance before you start the export.
A small team with a handful of repositories usually has a short migration. Git history can be mirrored in a single session, and the pull request record is small enough to export by hand or with a short script. The main effort is deciding what must be kept and rebuilding the working setup, not moving bulk data. Illustratively, a team with five repositories and no LFS can often finish the mirror and the permission rebuild in one planned window, but this depends on the state of your own repositories.
- Keep the decision list short: Decide which open pull requests and comments must survive, and archive the rest read-only.
- Rebuild permissions directly: Recreate a few teams and branch protection rules in Gitea by hand.
- Replace Pipelines simply: Move a small set of build jobs to Gitea Actions, which is designed to be compatible with GitHub Actions.
- Limit the parallel run: Two systems for a few weeks is usually enough for a small team.
- Document the cutover: Record the new clone URLs and hooks in one place for developers.
Confirm the repository count, sizes and open pull requests with your team before choosing a single cutover window.
A large estate with many projects and LFS-heavy repositories needs a phased plan. Git LFS objects are stored separately from normal Git history, so a mirror must include them, and you need to confirm that the Gitea instance has the storage and configuration to hold them. Large repositories also make export time and bandwidth the constraint, not the number of commands. The main planning work is sequencing waves by size and risk, and checking each wave before the next one starts.
- LFS inventory first: Identify which repositories use LFS and how much object storage they consume before you size the target.
- Waves by size: Migrate small and low-risk projects first, and move the largest LFS repositories in planned windows.
- Storage and backups: Size Gitea's storage and backup target for LFS objects as well as Git data.
- Dependency checks: Find build scripts and external links that point at Bitbucket URLs, since they break at cutover.
- Verification per wave: Compare commit counts, branch lists and LFS object checks before closing a source repository.
Confirm LFS storage limits, supported Gitea configuration and any Atlassian export restrictions with the vendors before setting wave dates.
What drives migration cost and duration, and how to keep each down
This table lists the factors that change the effort of moving Bitbucket repositories to self-hosted Gitea and explains how to reduce each one. Read it before scoping a migration, because the largest costs usually come from pull request history, permissions and Pipelines rewrites rather than from the Git data itself.
| Driver | Why it moves cost or effort | How to keep it down |
|---|---|---|
| Repository count and total size | Each repository needs a mirror, an LFS transfer and a verification pass. Bitbucket Cloud enforces a 4 GB repository limit, so large repositories need planning before the move. | Inventory every repository and its size first. Remove committed build output and large binaries from history where the team agrees, and confirm LFS object transfer with a test repository. |
| Pull request and comment history | Gitea's migration code has no Bitbucket importer, so pull requests and comments must be exported through the Bitbucket API and recreated or archived separately. Volume drives script work and review time. | Decide which pull requests must survive. Archive older pull requests as exported records and migrate only open or recently referenced ones. |
| Branch permission rules | Each rule must be re-created by hand in Gitea, and rules that depend on user groups need mapping to Gitea teams. Many rules multiply testing. | Consolidate rules before the move, remove rules on abandoned branches, and document the target permission model with the security owner. |
| Pipelines complexity | Bitbucket Pipelines definitions, variables and deployment steps must be rewritten for Gitea Actions. Pipeline variables cannot be read back from Bitbucket, so secrets must be re-entered. | Inventory pipelines by owner and retire unused ones. Start with the simplest build and test pipelines and confirm the Actions runner setup before rewriting deployment jobs. |
| Integrations to rebuild | Jira links, chat notifications, webhooks and deployment tools all point at Bitbucket endpoints and need new configuration in Gitea. | List each integration with its owner and keep only those with active use. Remove stale webhooks before cutover. |
| API rate limits during export | Bitbucket Cloud allows 1,000 requests per hour for most API resources, so large pull request exports run slowly and may need scheduling across days. | Export pull request data in batches, cache results, and confirm current limits in the Bitbucket Cloud documentation before estimating the export window. |
| Internal staff time for testing and training | Developers must verify history, check permissions and learn the new review flow. This recurring effort often costs more than the server. | Run a pilot with one team, write short runbooks for pull requests and Actions, and schedule training before the Bitbucket contract or Data Center renewal ends. |
Questions buyers ask before moving from Bitbucket to Gitea
How much effort and time does a Bitbucket to Gitea migration take?
The effort depends on what you move, not on the number of repositories alone. Cloning Git history is the quick part, while pull requests, comments, branch permissions, LFS objects and CI definitions each need their own work. The main drivers are the number of repositories with open pull request history, how much LFS content exists, how many branch permission rules must be rebuilt by hand, and how many Pipelines configurations must be rewritten for Gitea Actions. Gitea has no Bitbucket importer, so pull request history is a separate project. Ask any partner for a written scope that lists each of these items and the deliverables for each one before you agree on a timeline. Confirm the exact export limits of your Bitbucket plan, since API rate limits can stretch a bulk export.
What does our team need to provide for the migration?
You need to provide access and decisions, which are usually the bottleneck. Expect to supply an inventory of repositories, a list of active branches and protected branches, the current branch permission rules, and a list of users who need accounts on the new server. You will also need an administrator for the Bitbucket side with rights to export data, an owner for the target Gitea server and its database, and a person who can sign off on which open pull requests and comments must be preserved. Your engineers must confirm which Pipelines jobs still matter and which secrets need to be recreated in the new CI system, because Pipelines variables cannot be read back from Bitbucket.
Can our internal staff run the migration without a partner?
Yes, a team with Git administration skills can clone and mirror repositories into Gitea without outside help. The harder parts are the ones with no built-in tool: exporting pull request and comment history through the Bitbucket API, rebuilding permissions, rewriting pipelines and validating that nothing was lost. Gitea's migration documentation lists importers for GitHub, AWS CodeCommit and GitLab, but not Bitbucket, so anything beyond plain Git is custom work. Internal staff should decide whether they have time to build and test that tooling while keeping normal operations running. A fixed-scope engagement with written deliverables can cover the parts your team does not have capacity for, and DeployOpen plans, implements, integrates and documents self-hosted platforms in your own infrastructure.
Can pull requests and comments be imported into Gitea from Bitbucket?
Not with a built-in Bitbucket importer. Gitea's repository migration documentation describes migrations from GitHub, AWS CodeCommit and GitLab, and it lists no Bitbucket or Azure DevOps importer. Repositories from those services therefore arrive as plain Git, without pull requests, reviews, comments or issues. Teams that need that history usually export it from the Bitbucket API within rate limits, store it as an archive, and link to it from new Gitea issues or documentation. Gitea's own migration code does include importers for other platforms, so check whether an intermediate platform could carry the data. Confirm with any vendor or partner exactly what history they can preserve before you agree that it is in scope.
How does Gitea's MIT license and CommitGo support compare with other forges?
Gitea is MIT licensed, so you can run, modify and redistribute it with few license obligations. CommitGo, Inc. provides leadership and commercial support for Gitea and sells Gitea Enterprise, which adds SAML 2.0 service provider support, audit logging, organization-level branch protection inheritance, IP allowlisting, mandatory two-factor authentication and dependency scanning. GitLab is open core, with MIT-licensed code outside its proprietary ee/ directory, and Forgejo is GPL-3.0-or-later from v9.0 with domains held by Codeberg e.V. Choose based on which features you need, which license terms your legal team accepts, and which support model you want. Confirm the current feature list and license terms of each edition with the vendor before you sign.
What happens to Bitbucket Pipelines and Jira links after the move?
Pipelines does not transfer to Gitea. You need to rewrite each pipeline for Gitea Actions, which is designed to be compatible with GitHub Actions, and then test every job, since compatibility does not guarantee identical behavior. Pipelines variables and secured values cannot be read back from Bitbucket, so each secret must be recreated in the new system and rotated where needed. Jira links are a separate issue, because Gitea has no built-in Jira integration. Commit messages and branch names that reference Jira keys will still exist as text, but automatic linking and status updates will stop unless you replace them with webhooks or another integration. Ask your team to inventory every Jira link and automation before cutover so that nothing breaks silently.
What should we check before we start a Bitbucket to Gitea migration?
Start with an inventory and a written scope. List every repository, its size, its LFS usage, its open pull requests, its branch permission rules and its pipelines, and mark which items must be preserved. Check Bitbucket's repository size and API request limits for your plan so that the export schedule is realistic. Decide how the new Gitea server will be hosted, backed up and secured inside your own infrastructure, and confirm which database Gitea will use. Then run a pilot with a small set of repositories, verify clone integrity and access rights, and only then schedule cutover. Keep the Bitbucket contract active until the archive and the validation sign-off are complete.
What usually goes wrong and how to prevent it
Most failed Bitbucket to Gitea moves do not fail on the Git history, which copies cleanly. They fail on the context around the code: review threads, LFS objects, permissions and CI. Each card below names one of these risks and the step that prevents it.
Pull request context lost
Gitea has no Bitbucket importer, so pull requests, inline review comments and approvals do not arrive with the repository. If nobody exports them before the Bitbucket contract ends, that history is gone. Export pull requests, comments and tasks through the Bitbucket API into an archive that your auditors can read, and keep it alongside the new Gitea repositories. Confirm which fields your export captures before you rely on it.
LFS objects missing from mirrors
A plain Git mirror copies commits but may not copy Git LFS objects, so large binaries show up as pointer files after the move. Clone each repository with LFS enabled, then push LFS content to the new Gitea instance and verify it with a fresh clone on a clean machine. Check that the storage backend has room for the LFS volume before the cutover date.
API rate limits stalling exports
Bulk export scripts that call the Bitbucket API will hit request limits on large workspaces, and the export stops partway through a project. Plan the export in batches, cache responses, and schedule the largest projects first so retries do not compete with the final sync. Ask Atlassian for the current limits that apply to your plan, because the published cap is a starting point rather than a guarantee.
Permissions drifting during parallel run
While teams keep working in Bitbucket and Gitea in parallel, branch permissions, team membership and default reviewers change in one system but not the other. Gitea branch protection must be re-created by hand, so a protected main branch in Bitbucket can become writable in Gitea without anyone noticing. Keep a written permission matrix, reconcile it at each sync, and freeze permission changes in both systems during the final cutover window.
Pipelines failing on Actions syntax
Gitea Actions is designed to be compatible with GitHub Actions, but Bitbucket Pipelines YAML uses different keys, step definitions and variable names. Pipelines that worked in Bitbucket will fail on the first Gitea run if they are copied unchanged. Translate one representative pipeline at a time, run it on a test runner, and compare artifacts and deployment steps against the Bitbucket output before retiring the original.
Secrets that cannot be read back
Bitbucket Pipelines variables marked secured cannot be read back through the interface or API, so the export cannot carry them into Gitea. Inventory every secured variable now, identify its owner, and reissue each credential in Gitea secrets or your external vault. Revoke the old values only after the replacement pipeline has passed a full run, otherwise deployments break at the moment you are least able to diagnose them.
What the team should decide before scoping the work
The first decision is whether Gitea is the right forge at all. Gitea is a reasonable choice when the team wants a single binary, a small operational footprint and an MIT-licensed core, and when its built-in Gitea Actions, which are designed to be compatible with GitHub Actions, can run the pipelines the team already has. It is a weaker fit if the team depends on a full DevOps suite with issues, registries and CI tied to one platform, or if its pipelines use Bitbucket Pipelines features that have no Actions equivalent. In that case, compare GitLab, which can import Bitbucket Cloud and Bitbucket Server projects directly, and Forgejo, which is GPL-3.0-or-later from v9.0 and governed by a non-profit. Check the license and support model against the organization's procurement rules before the database and runner design starts, because a change of forge later means another migration.
The second decision is where the Gitea instance and its backups live. Gitea supports MySQL, PostgreSQL, SQLite and MSSQL, and the choice of database, the storage for repositories and LFS objects, and the location of backups all determine the recovery plan. Confirm which data region the organization requires, since a self-hosted instance inherits whatever residency rules apply to its datacenter or cloud account. Decide who operates the host, who holds the restore keys and how often a restore is rehearsed. Gitea's own upgrade cadence, including the v28 line that followed v1.27, should be built into the maintenance calendar rather than left to whoever first installed the server.
The third and fourth decisions are who owns permissions and when cutover happens. Bitbucket project and repository permissions, branch restrictions and default reviewer rules do not move with a Git mirror, so name the people who will recreate them in Gitea organizations, teams and branch protection, and agree the mapping before anyone is granted write access. Then set the cutover window. Pull requests, comments and review history stay in Bitbucket unless they are exported through the API, which is rate limited, so the team needs to decide whether to archive them, run both systems for a period, or accept a read-only Bitbucket. Agree a freeze on pushes, a rollback path and a named owner for the go or no-go call. These choices, once written down, define the scope a partner or internal team can price and plan.
How DeployOpen works on this
DeployOpen plans, implements, customizes, integrates, hardens, backs up, upgrades, documents and supports self-hosted open-source platforms inside your own cloud accounts, data centers or air-gapped networks. For a move from Bitbucket to Gitea, that means one written scope covering the repository mirror, the pull request record, branch permissions and the CI replacement.
How we scope
- Inventory every Bitbucket Cloud or Data Center workspace, project, repository, LFS object and wiki before any target is sized.
- Record which pull request comments, reviews and Jira links must survive, and which can be archived read-only.
- Agree the scope, deliverables and timelines in writing before work starts, since most engagements are fixed-scope.
How we build
- Mirror Git history and LFS objects into Gitea on infrastructure you control, then verify commit counts and tags against the source.
- Rebuild branch protection and team permissions by hand, because no Bitbucket importer carries them across.
- Replace Pipelines with Gitea Actions or another agreed CI service, and test each pipeline against a copy of the repository first.
How we hand over
- Document the target configuration, backup jobs, restore steps and the mapping of every migrated repository and permission.
- Provide a cutover runbook that states the freeze window, the redirect or remote change for developers, and the rollback point.
- Deliver the archive of exported pull request and issue records so auditors and teams can review historical decisions later.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers after handover, scoped in writing.
- Plan Gitea upgrades and backup restore tests on a schedule your change process approves.
- Ask any quote to separate one-time migration work from recurring support, hosting and staff time on your side.

