During transitions from Bitbucket to GitLab, teams may still push code to Bitbucket. Keeping both Bitbucket and GitLab repositories in sync ensures nothing gets lost, avoids disruption, and allows for a gradual migration. Here's a practical guide detailing two reliable ways to achieve this, making the migration far less disruptive for your development teams. 📖 Table of Contents Introduction Prerequisites Option 1: Using GitLab Repository Mirroring Option 2: Sync Using GitLab CI/CD and Bitbucket Webhooks Comparing Your Options Testing Your Setup Benefits Conclusion Introduction Prerequisites Option 1: Using GitLab Repository Mirroring Option 2: Sync Using GitLab CI/CD and Bitbucket Webhooks Comparing Your Options Testing Your Setup Benefits Conclusion Introduction When moving from Bitbucket to GitLab, teams often can't immediately stop using Bitbucket. Developers still push changes, open pull requests, and merge branches, which makes synchronization crucial. Keeping repositories in sync ensures development continuity without forcing an immediate platform switch, giving your team more breathing room to adapt to GitLab gradually. Prerequisites Basic access (developer or maintainer permissions) to both your Bitbucket and GitLab repositories. Permission to configure webhooks and CI/CD pipelines on both platforms. Basic access (developer or maintainer permissions) to both your Bitbucket and GitLab repositories. Permission to configure webhooks and CI/CD pipelines on both platforms. Option 1: Using GitLab Repository Mirroring GitLab's built-in mirroring is the simplest way to sync repositories from Bitbucket. Steps to Set Up Mirroring: In your GitLab project, navigate to Settings > Repository. Expand the Mirroring repositories section. Enter your Bitbucket repository URL: https://bitbucket.org/username/repository.git Provide your Bitbucket username and password or access token. Choose Pull to sync from Bitbucket to GitLab. Select your desired sync interval (e.g., every 5 minutes). Click Mirror repository to enable mirroring. In your GitLab project, navigate to Settings > Repository. In your GitLab project, navigate to Settings > Repository. Settings > Repository Expand the Mirroring repositories section. Expand the Mirroring repositories section. Mirroring repositories Enter your Bitbucket repository URL: https://bitbucket.org/username/repository.git Enter your Bitbucket repository URL: https://bitbucket.org/username/repository.git https://bitbucket.org/username/repository.git Provide your Bitbucket username and password or access token. Provide your Bitbucket username and password or access token. Choose Pull to sync from Bitbucket to GitLab. Choose Pull to sync from Bitbucket to GitLab. Pull Select your desired sync interval (e.g., every 5 minutes). Select your desired sync interval (e.g., every 5 minutes). Click Mirror repository to enable mirroring. Click Mirror repository to enable mirroring. Mirror repository Option 2: Sync Using GitLab CI/CD and Bitbucket Webhooks If repository mirroring isn't available in your GitLab instance, or you require more customization, you can set up synchronization using GitLab CI/CD pipelines and Bitbucket webhooks. Step 1: Add .gitlab-ci.yml to Both Bitbucket and GitLab .gitlab-ci.yml Create a .gitlab-ci.yml file and add it to both Bitbucket and GitLab repositories. This prevents synchronization issues that could occur when mirroring overwrites your pipeline configuration. .gitlab-ci.yml add it to both Bitbucket and GitLab repositories Here's the YAML configuration: stages: - sync sync_from_bitbucket: stage: sync only: - schedules # Trigger via GitLab scheduled pipelines - triggers # Trigger via external trigger tokens (e.g., webhooks) - web # Allow manual web-triggered runs from the GitLab UI script: - git config --global user.name "your_username" - git config --global user.email "your_email@example.com" - git clone --mirror https://${BITBUCKET_USER}:${BITBUCKET_TOKEN}@bitbucket.org/username/repository.git bitbucket-mirror # Clone Bitbucket repo as a bare mirror - cd bitbucket-mirror # Navigate into the cloned mirror - git push --mirror https://${GITLAB_USER}:${GITLAB_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git # Push mirror to GitLab stages: - sync sync_from_bitbucket: stage: sync only: - schedules # Trigger via GitLab scheduled pipelines - triggers # Trigger via external trigger tokens (e.g., webhooks) - web # Allow manual web-triggered runs from the GitLab UI script: - git config --global user.name "your_username" - git config --global user.email "your_email@example.com" - git clone --mirror https://${BITBUCKET_USER}:${BITBUCKET_TOKEN}@bitbucket.org/username/repository.git bitbucket-mirror # Clone Bitbucket repo as a bare mirror - cd bitbucket-mirror # Navigate into the cloned mirror - git push --mirror https://${GITLAB_USER}:${GITLAB_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git # Push mirror to GitLab Update "your_username" and "your_email@example.com" with your actual Git details. "your_username" "your_email@example.com" Note: All secrets (tokens, usernames) should be stored securely in GitLab CI/CD variables and referenced in the script to avoid hardcoding sensitive data. Note: All secrets (tokens, usernames) should be stored securely in GitLab CI/CD variables and referenced in the script to avoid hardcoding sensitive data. Note: All secrets (tokens, usernames) should be stored securely in GitLab CI/CD variables and referenced in the script to avoid hardcoding sensitive data. Step 2: Configure GitLab CI/CD Variables Navigate to GitLab: Settings > CI/CD > Variables, then add: Settings > CI/CD > Variables BITBUCKET_USER: Your Bitbucket username BITBUCKET_TOKEN: Your Bitbucket access token or app password GITLAB_USER: Your GitLab username GITLAB_TOKEN: Your GitLab personal access token (scope: write_repository) BITBUCKET_USER: Your Bitbucket username BITBUCKET_USER BITBUCKET_TOKEN: Your Bitbucket access token or app password BITBUCKET_TOKEN GITLAB_USER: Your GitLab username GITLAB_USER GITLAB_TOKEN: Your GitLab personal access token (scope: write_repository) GITLAB_TOKEN write_repository Step 3: Create a Pipeline Trigger Token in GitLab In GitLab, navigate to: Settings > CI/CD > Pipeline triggers. Generate a new trigger token. Note your GitLab project's project ID from your project home page. In GitLab, navigate to: Settings > CI/CD > Pipeline triggers. Settings > CI/CD > Pipeline triggers Generate a new trigger token. Note your GitLab project's project ID from your project home page. project ID Step 4: Add a Webhook in Bitbucket In Bitbucket: Navigate to your repository settings (Repository settings > Webhooks). Add a webhook using the URL format: https://gitlab.com/api/v4/projects/{project_id}/ref/{branch_name}/trigger/pipeline?token={trigger_token} Navigate to your repository settings (Repository settings > Webhooks). Navigate to your repository settings (Repository settings > Webhooks). Repository settings > Webhooks Add a webhook using the URL format: https://gitlab.com/api/v4/projects/{project_id}/ref/{branch_name}/trigger/pipeline?token={trigger_token} Add a webhook using the URL format: https://gitlab.com/api/v4/projects/{project_id}/ref/{branch_name}/trigger/pipeline?token={trigger_token} https://gitlab.com/api/v4/projects/{project_id}/ref/{branch_name}/trigger/pipeline?token={trigger_token} Replace placeholders accordingly: {project_id}: Your GitLab project ID {branch_name}: Your main branch (main or master) {trigger_token}: The pipeline trigger token from GitLab. Choose push or merge events (or others as needed) to trigger synchronization. {project_id}: Your GitLab project ID {project_id} {branch_name}: Your main branch (main or master) {branch_name} main master {trigger_token}: The pipeline trigger token from GitLab. {trigger_token} Choose push or merge events (or others as needed) to trigger synchronization. push merge Comparing Your Options Feature GitLab Repository Mirroring GitLab CI/CD + Webhook Complexity Easy Moderate Available without Mirroring No Yes Customization Limited High Trigger Type Scheduled Webhook & scheduled Maintains Repository History Yes Yes Feature GitLab Repository Mirroring GitLab CI/CD + Webhook Complexity Easy Moderate Available without Mirroring No Yes Customization Limited High Trigger Type Scheduled Webhook & scheduled Maintains Repository History Yes Yes Feature GitLab Repository Mirroring GitLab CI/CD + Webhook Feature Feature GitLab Repository Mirroring GitLab Repository Mirroring GitLab CI/CD + Webhook GitLab CI/CD + Webhook Complexity Easy Moderate Complexity Complexity Easy Easy Moderate Moderate Available without Mirroring No Yes Available without Mirroring Available without Mirroring No No Yes Yes Customization Limited High Customization Customization Limited Limited High High Trigger Type Scheduled Webhook & scheduled Trigger Type Trigger Type Scheduled Scheduled Webhook & scheduled Webhook & scheduled Maintains Repository History Yes Yes Maintains Repository History Maintains Repository History Yes Yes Yes Yes Testing Your Setup To verify synchronization: Push changes to your Bitbucket repository. Use GitLab’s CI/CD pipeline logs or Bitbucket's webhook testing tools to confirm synchronization. Adjust as needed based on pipeline feedback or errors. Push changes to your Bitbucket repository. Use GitLab’s CI/CD pipeline logs or Bitbucket's webhook testing tools to confirm synchronization. Adjust as needed based on pipeline feedback or errors. Benefits Setting up synchronization provides: Continuous integration across platforms during migration. Full preservation of repository history, tags, and branches. Minimal disruption to developer workflows. Flexibility in migration timelines. Continuous integration across platforms during migration. Full preservation of repository history, tags, and branches. Minimal disruption to developer workflows. Flexibility in migration timelines. Conclusion Synchronizing repositories between Bitbucket and GitLab doesn't have to be complicated. Using either GitLab's built-in mirroring or CI/CD pipelines with webhooks, you can ensure smooth migrations and minimize headaches for developers.