#Bitbucketのgitリポジトリのバックアップを取得するスクリプトを書いてみました。
BitbucketのAPIを呼び出してアカウントに紐づけられているリポジトリの一覧を取得して、git clone --mirrorでリポジトリの複製を行ないます。
過去にリポジトリが複製済みだった場合にはgit fetch --allでリポジトリの内容を更新しています。
※BitbucketのAPIからのレスポンスのJSONを解析するのにjqを使っているのでjqがインストールされている必要があります。
#!/bin/bash
SCRIPT_DIR=$(cd $(dirname $0); pwd)
BITBUCKET_USER=bitbucket_user@email.address
BITBUCKET_PASSWORD=butbucket.password
BITBUCKET_OWNER=ownername
next_page_url="https://api.bitbucket.org/2.0/repositories/$BITBUCKET_OWNER"
while [ ! -z "$next_page_url" ] && [ "$next_page_url" != "null" ]; do
bitbucket_response=`curl --user $BITBUCKET_USER:$BITBUCKET_PASSWORD $next_page_url`
bitbucket_repositories=`echo $bitbucket_response | jq -r '.values[].links.clone[].href' | grep "^git"`
for repository_path in $bitbucket_repositories; do
dir=`echo "$(dirname $repository_path)" | sed -e 's/:/\//g' | sed -e 's/^git@//g'`
if [ ! -d "$dir" ]; then
mkdir -p "$dir"
fi
repo=$(basename $repository_path)
if [ ! -d "$dir/$repo" ]; then
(cd $dir; git clone --mirror $repository_path)
else
(cd "$dir/$repo"; git fetch --all)
fi
done
next_page_url=`echo $bitbucket_response | jq -r '.next'`
done
JSONの解析にjqを使わずにColonel Richie氏が書かれたシェルスクリプト(sedやawkを利用)したparsrj.shで解析するなら、bitbucket_repositoriesを取得する部分を以下に差し替え
bitbucket_repositories=`echo $bitbucket_response | $SCRIPT_DIR/parsrj.sh | \
grep "\$\.values\[[0-9]*\]\.links\.clone\[[0-9*]\]\.href git" | \
sed -e 's/\$\.values\[[0-9]*\]\.links\.clone\[[0-9*]\]\.href //g'`
##その後…
上記シェルスクリプトを使ってBitbucketのリポジトリのミラーを作って、参照系の処理ではミラーを使ってネットトラフィックの削減などを行なっていたのですが、このスクリプトだとオーナーが所有するリポジトリが全部横並びに展開されてしまい使いづらいとの指摘があったので、Bitbucketのレスポンスからリポジトリが所属するプロジェクトの情報も取得してリポジトリを<オーナー>/<プロジェクト>/以下に展開する様に改良を加えたのが以下のスクリプトです。
※Bitbucketのパスワードをスクリプト中に暗号化して埋め込むためにdecrypt_password.sh
を呼び出しています。
decrypt_password.sh
については「シェルスクリプトの中に安全にパスワードを埋め込む」を参照してください
#!/bin/bash
SCRIPT_DIR=$(cd $(dirname $0); pwd)
. $SCRIPT_DIR/decrypt_password.sh
BITBUCKET_USER=bitbucket_user@email.address
BITBUCKET_PASSWORD=`decrypt_password U2FsDGVkX1+tF5lcBC3+4/ztIYEpVr7jgThH9wYG9QE=`
BITBUCKET_OWNER= ownername
page=1
next_page_url="https://api.bitbucket.org/2.0/repositories/$BITBUCKET_OWNER"
while [ ! -z "$next_page_url" ] && [ "$next_page_url" != "null" ]; do
bitbucket_response=`curl --user $BITBUCKET_USER:$BITBUCKET_PASSWORD $next_page_url 2> /dev/null`
num_values=`echo $bitbucket_response | jq -r '.values' | jq length`
for value_pos in $(seq 0 $((num_values - 1))); do
repository_info=`echo $bitbucket_response | jq -r ".values[$value_pos]"`
project_name=`echo $repository_info | jq -r ".project.name"`
# たぶん、マッチするのは1件だけのはず…
repository_path=`echo $repository_info | jq -r ".links.clone[].href" | grep "^git"`
# 常に owner = BITBUCKET_OWNER なのではないか?
owner=`echo "$(dirname $repository_path)" | sed -e 's/:/\//g' | sed -e 's/^git@//g'`
# project.name が無いことはあるのか?
if [ -z "$project_name" ]; then
dir="$owner"
else
dir="$owner/$project_name"
fi
if [ ! -d "$dir" ]; then
mkdir -p "$dir"
fi
repo=$(basename $repository_path)
if [ ! -d "$dir/$repo" ]; then
(cd $dir; git clone --mirror $repository_path)
else
(cd "$dir/$repo"; git fetch --all)
fi
done
next_page_url=`echo $bitbucket_response | jq -r '.next'`
echo next=$next_page_url
done