Skip to main content

Overview

Gitea provides a comprehensive migration system that allows you to import repositories from external Git hosting platforms. The migration process can transfer not only the Git repository itself, but also issues, pull requests, labels, milestones, releases, and other metadata.

Supported Platforms

Gitea supports migrating from the following platforms: Reference: modules/structs/repo.go:325-336

Migration Options

When migrating a repository, you can configure the following options:
Reference: modules/migration/options.go:9-44

Migrating from GitHub

Migrating from GitLab

Migrating from Bitbucket

Bitbucket repositories can be migrated as plain Git repositories:
Plain Git migrations only transfer the Git repository and wiki. Issues, pull requests, and other metadata are not migrated.

Authentication Methods

Different platforms support different authentication methods:

Token Authentication

Supported platforms: GitHub, GitLab, Gitea
Reference: modules/structs/repo.go:405-411

Username and Password

Supported by all platforms, but tokens are recommended when available.

SSH Keys

For plain Git migrations, you can use SSH URLs with configured SSH keys.

Migration Process

The migration process follows these steps:

URL Restrictions

For security, Gitea restricts which URLs can be migrated from:

Allowed Domains

Configure allowed domains in app.ini:
By default, only external hosts are allowed. Internal/local network addresses are blocked. Reference: services/migrations/migrate.go:514-532

Blocked Domains

Block specific domains:

Local File System

Administrators can migrate from local file system paths:
Reference: services/migrations/migrate.go:51-68

LFS Migration

Gitea can migrate Git LFS (Large File Storage) objects:

Enable LFS migration

Check the Migrate LFS option when creating the migration.

Custom LFS endpoint

If the source repository uses a custom LFS server:
Reference: services/migrations/migrate.go:116-121

LFS authentication

LFS migration uses the same authentication credentials as the Git repository.

Mirror Repositories

You can create a mirror instead of a one-time migration:

Pull mirrors

  • Periodically sync from source repository
  • Read-only on Gitea (pushes go to upstream)
  • Configured during migration by checking This repository will be a mirror

Mirror interval

Set how often the mirror syncs:
Or specify per-repository:
Reference: modules/migration/options.go:40

Retry and Error Handling

Migrations support automatic retries for transient failures:
Reference: services/migrations/migrate.go:170-173 Configure in app.ini:

Batch Size Configuration

For large repositories, Gitea processes data in batches:
Reference: services/migrations/migrate.go:253-395 This prevents memory issues and database timeouts on large migrations.

Migrating via API

You can trigger migrations programmatically using the Gitea API:
Reference: modules/structs/repo.go:369-402

Migration Status

During migration, Gitea provides progress updates:
Reference: services/migrations/migrate.go:179-510

Troubleshooting

Migration Fails with URL Error

Error: Invalid clone address Solutions:
  • Verify the repository URL is correct
  • Check that the domain is not in the blocked list
  • Ensure the domain is in the allowed list if configured
  • For private repositories, verify authentication credentials

Authentication Failures

Error: Authentication failed Solutions:
  • For GitHub/GitLab: Verify token has required scopes
  • For username/password: Check credentials are correct
  • For SSH: Ensure SSH key is properly configured
  • Check if two-factor authentication is blocking access

Partial Migration

Issue: Git repository migrated, but issues/PRs missing Solutions:
  • Verify you selected those items during migration setup
  • Check that your token has permission to read issues/PRs
  • Review migration logs for specific errors
  • Some platforms may rate-limit API requests

Large Repository Timeout

Issue: Migration times out for large repositories Solutions:
  • Increase timeout in app.ini:
  • Consider migrating Git data first, then metadata separately
  • Use mirror mode for continuous sync instead of one-time migration

LFS Objects Not Migrated

Issue: LFS files show as pointers instead of actual content Solutions:
  • Ensure Migrate LFS was checked during migration
  • Verify LFS is enabled in source repository
  • Check authentication has access to LFS endpoint
  • Confirm LFS endpoint URL if using custom server

Best Practices

  1. Test with small repositories first - Verify the migration process works before migrating large or critical repositories
  2. Use tokens over passwords - Tokens provide better security and can be scoped to specific permissions
  3. Review permissions - Ensure your authentication token has all necessary scopes:
    • Repository read access
    • Issue read access
    • Pull request read access
    • Release read access
  4. Check rate limits - Some platforms (especially GitHub) have API rate limits. Large migrations may need to be scheduled or split.
  5. Verify migrated data - After migration:
    • Check that all branches were migrated
    • Verify issue and PR counts match
    • Test that LFS files downloaded correctly
    • Confirm release assets are accessible
  6. Plan for downtime - During migration:
    • Source repository should not receive new commits
    • Coordinate with team to avoid conflicts
    • Consider making source repository read-only
  7. Update integrations - After migration:
    • Update CI/CD pipelines
    • Reconfigure webhooks
    • Update local git remotes:
  8. Archive source repository - After successful migration and verification:
    • Archive the source repository (don’t delete immediately)
    • Add a redirect notice in README
    • Keep source accessible for 30-90 days

Advanced: Custom Migrations

For platforms not natively supported, you can implement a custom downloader:
Reference: modules/migration/downloader.go:14-27 Implement this interface and register your downloader factory to add support for additional platforms.