Skip to content

ssntpl/bb2gh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bb2gh — Bitbucket to GitHub migration

A small tool to migrate repositories from Bitbucket to GitHub. It uses the Bitbucket API to list repos, creates matching private repos on GitHub, and mirrors each repository (all branches, tags, and history) via git push --mirror.


What it does

  • migrate.py — Full automation: lists repos from your Bitbucket workspace, creates each repo on GitHub with gh repo create, then clones (bare) from Bitbucket and pushes a mirror to GitHub. Credentials and workspace names come from a .env file.
  • upload.sh — For when you already have bare clones (e.g. repo.git folders): creates the GitHub repo and runs git push --mirror for each. The GitHub org in the script is hardcoded (see below).

Prerequisites

  1. Python 3 (3.7+)
  2. Git installed and available in your PATH
  3. GitHub CLI (gh) — used to create repos and authenticate pushes
  4. Bitbucket App Password (not your normal password)
    • Bitbucket → Personal settings → App passwords → Create. Give it Repository: Read (and any other permissions you need).

Setup

1. Clone this repo and enter the directory

cd /path/to/bb2gh

2. Create a virtual environment (recommended)

python3 -m venv .venv
source .venv/bin/activate   # On Windows: .venv\Scripts\activate

3. Install dependencies

pip install -r requirements.txt

4. Configure credentials via .env

Copy the example env file and edit it with your values:

cp .env.example .env

Edit .env and set:

Variable Required Description
BITBUCKET_USERNAME Yes Your Bitbucket username (e.g. nuclearsam)
BITBUCKET_APP_PASSWORD Yes Bitbucket App Password (from step 4 in Prerequisites)
BITBUCKET_WORKSPACE Yes Bitbucket workspace slug (from the workspace URL)
GITHUB_WORKSPACE Yes GitHub org or username where repos will be created (e.g. ssntpl)
GITHUB_TOKEN No Only needed if you use GitHub API code; gh CLI uses its own auth

Important: Never commit .env — it is listed in .gitignore. Only .env.example (with placeholders) should be in the repo.


Usage

Option A: Full migration with migrate.py

From the project root (with .env configured and gh logged in):

python migrate.py

This will:

  1. Check that required env vars are set (exits with a clear message if not).
  2. Call the Bitbucket API to list repositories in your workspace (with pagination).
  3. For each repo:
    • Create a private GitHub repo {GITHUB_WORKSPACE}/{repo_slug} with the same description.
    • Clone the Bitbucket repo as a bare clone.
    • Run git push --mirror to the new GitHub repo (all refs and history).
    • Remove the local bare clone.

Pagination note: The script starts from a specific page of the Bitbucket API (see “Configuration” below). If you have many repos, it will follow the next page URL and process all pages until there are no more.

Option B: Push existing bare clones with upload.sh

If you already have bare clones (e.g. myrepo.git directories) in the current folder:

  1. Ensure GitHub CLI is installed and logged in (gh auth login).
  2. The script uses a hardcoded GitHub org (ssntpl). Edit upload.sh and replace ssntpl with your GitHub org/username if different.
  3. Run:
./upload.sh

For each *.git directory it will:

  • Create a private repo ssntpl/<repo_name> on GitHub.
  • Run git push --mirror to that repo.

Make sure the script is executable: chmod +x upload.sh if needed.


Environment variables reference

Defined in .env (see .env.example):

  • BITBUCKET_USERNAME — Bitbucket username.
  • BITBUCKET_APP_PASSWORD — Bitbucket App Password.
  • BITBUCKET_WORKSPACE — Bitbucket workspace slug.
  • GITHUB_WORKSPACE — GitHub org or user for new repos.
  • GITHUB_TOKEN — Optional; for GitHub API usage only.

Configuration and tweaks

  • Start page for Bitbucket listing
    In migrate.py, the initial URL is:

    url = f"https://api.bitbucket.org/2.0/repositories/{bitbucket_workspace}?page=8"

    To process from the first page, change page=8 to page=1 or remove the ?page=8 part (Bitbucket defaults to page 1).

  • Repo visibility
    Repos are created with --private. To create public repos, change the gh repo create line in migrate.py (remove or replace --private).

  • upload.sh
    The GitHub org is hardcoded as ssntpl. Edit the script to use your org, or source a variable from a file if you prefer.


Troubleshooting

  • “Missing required env vars”
    Copy .env.example to .env, fill in all required variables, and run from the same directory (or ensure load_dotenv() can find .env).

  • “Failed to fetch Bitbucket repositories”
    Check BITBUCKET_USERNAME, BITBUCKET_APP_PASSWORD, and BITBUCKET_WORKSPACE. Ensure the App Password has at least Repository: Read.

  • “Failed to create … on GitHub”
    Run gh auth login and ensure you have permission to create repos in the org/user set in GITHUB_WORKSPACE. If the repo already exists, the script will skip creation; you may need to delete it on GitHub or change the script to handle existing repos.

  • Clone or push errors
    Ensure git and gh are on your PATH and that your Bitbucket clone URL (SSH or HTTPS) is accessible from your machine (SSH keys or credentials configured as needed).


License

Use and modify as you like. No warranty.

About

Simple python script to migrate all your repositories from Bitbucket to Github

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors