Created
October 31, 2025 23:13
-
-
Save sunsided/3411ae2cb6c6a57ed1d57382dd75ab25 to your computer and use it in GitHub Desktop.
Convert bazaar repos from lp directory into git repos in gh directory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -Eeuo pipefail | |
| # Migrates Bazaar branches in ./lp/<name> to bare Git repos in ./gh/<name>.git | |
| # If ./lp/<name> is missing (or not a bzr branch), it will "brz branch lp:<name> ./lp/<name>". | |
| # | |
| # Optional env: | |
| # DEFAULT_BRANCH=main # rename 'master' to 'main' and set HEAD accordingly | |
| # ONLY=<comma,separated,names> # process only these names (matching subdirs or Launchpad names) | |
| require() { command -v "$1" >/dev/null 2>&1 || { echo "Missing: $1" >&2; exit 1; }; } | |
| require brz | |
| require git | |
| ROOT="${PWD}" | |
| LP_DIR="${ROOT}/lp" | |
| GH_DIR="${ROOT}/gh" | |
| CACHE_DIR="${ROOT}/.cache-bzr2git" | |
| mkdir -p "$LP_DIR" "$GH_DIR" "$CACHE_DIR" | |
| # Expand list of projects | |
| declare -a names=() | |
| if [[ -n "${ONLY:-}" ]]; then | |
| IFS=',' read -r -a names <<<"$ONLY" | |
| else | |
| while IFS= read -r -d '' path; do | |
| base="$(basename "$path")" | |
| names+=("$base") | |
| done < <(find "$LP_DIR" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z) | |
| fi | |
| if [[ "${#names[@]}" -eq 0 ]]; then | |
| echo "No projects found under $LP_DIR and no ONLY=… given." >&2 | |
| exit 1 | |
| fi | |
| for name in "${names[@]}"; do | |
| echo "────────────────────────────────────────────────────────────" | |
| echo "Project: $name" | |
| BZR_DIR="${LP_DIR}/${name}" | |
| GIT_DIR="${GH_DIR}/${name}.git" | |
| BZR_MARKS="${CACHE_DIR}/${name}.bzr.marks" | |
| GIT_MARKS="${CACHE_DIR}/${name}.git.marks" | |
| # 1) Ensure we have a local Bazaar branch; if not, try Launchpad. | |
| if [[ ! -d "${BZR_DIR}/.bzr" ]]; then | |
| echo "No .bzr in ${BZR_DIR}; attempting: brz branch lp:${name} ${BZR_DIR}" | |
| mkdir -p "$LP_DIR" | |
| brz branch "lp:${name}" "${BZR_DIR}" | |
| fi | |
| # Quick sanity info | |
| echo "Bazaar info:" | |
| (cd "${BZR_DIR}" && brz info | sed 's/^/ /') | |
| # 2) Prepare bare git target | |
| if [[ ! -d "${GIT_DIR}" ]]; then | |
| echo "Initializing bare git repo: ${GIT_DIR}" | |
| git init --bare "${GIT_DIR}" >/dev/null | |
| fi | |
| # 3) Stream Bazaar → Git with per-project marks (idempotent & re-runnable) | |
| echo "Importing history (this may take a moment)…" | |
| # Create marks files if missing to let fast-import update them | |
| : > "${BZR_MARKS}" || true | |
| : > "${GIT_MARKS}" || true | |
| # Export + import in one pipe | |
| brz fast-export --export-marks="${BZR_MARKS}" "${BZR_DIR}" \ | |
| | git --git-dir="${GIT_DIR}" fast-import --export-marks="${GIT_MARKS}" | |
| # 4) Optional: rename default branch (e.g., master → main) and set HEAD | |
| if [[ -n "${DEFAULT_BRANCH:-}" ]]; then | |
| echo "Setting default branch to '${DEFAULT_BRANCH}' (renaming if needed)…" | |
| # Try to rename master → DEFAULT_BRANCH if master exists | |
| if git --git-dir="${GIT_DIR}" show-ref --verify --quiet refs/heads/master; then | |
| if [[ "${DEFAULT_BRANCH}" != "master" ]]; then | |
| git --git-dir="${GIT_DIR}" branch -m master "${DEFAULT_BRANCH}" || true | |
| fi | |
| fi | |
| # Ensure HEAD points at DEFAULT_BRANCH (create it if importer used a different name) | |
| if git --git-dir="${GIT_DIR}" show-ref --verify --quiet "refs/heads/${DEFAULT_BRANCH}"; then | |
| git --git-dir="${GIT_DIR}" symbolic-ref HEAD "refs/heads/${DEFAULT_BRANCH}" | |
| fi | |
| fi | |
| # 5) Report refs | |
| echo "Heads:" | |
| git --git-dir="${GIT_DIR}" for-each-ref --format=' %(refname:short)' refs/heads/ | sort || true | |
| echo "Tags:" | |
| git --git-dir="${GIT_DIR}" for-each-ref --format=' %(refname:short)' refs/tags/ | sort || true | |
| echo "Done: ${GIT_DIR}" | |
| done | |
| echo "All done. Bare Git repos are in: ${GH_DIR}" | |
| echo "Tip: to inspect one repo, run: git clone ./gh/<name>.git" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment