こんにちは。木村です。2018年も早くも年末ですが、年末といえば大掃除ですね。
最近、社内でGitHubのOrganizationを作成しました。
それに伴い、社内の適当なサーバに置いたリポジトリだったり、VPSに立てていたGitLabだったり、その他色んな所に散らばっていたリポジトリを全てGitHubに集約する大掃除を行いましたので、その手順等々を書いていきます。
移行対象の把握
まずはこれが大事ですね。今回は一部(SVNとか…)を除いてどこで管理しているかは把握していたのでそこまで難しくはありませんでした。
ただ、GitLabのPersonalに紐付くアカウントについては把握しきれなかったので、必要に応じて各自で移行するようお願いしています。
一覧を作った後に全体に展開して、過不足や移行の必要が無いリポジトリの有無などを確認します。
移行作業
いざ把握すればあとは移行するだけです。今回は移行する詳細な中身として次のように設定しました。
- リポジトリのログとブランチ、タグは全て移行する
- その他の、IssueやCI/CDに紐付く設定は移行しない
Gitの仕組みとしてリポジトリに紐付くデータは簡単に移行しますが、その他は移行しないというシンプルな仕組みです。
その後は実作業なのですが、次の手順が必要です。
- GitHubにリポジトリを作成する
- 旧リポジトリのデータをgit cloneする
- originをGitHubに変更する
- 全てのタグやブランチをプッシュする
これが片手で数えられるくらいなら良いのですが、大体80リポジトリ前後あるため、どう考えても辛いですね。
ベアリポジトリを利用した移行手順はGitHubのドキュメント(これは正確にいうとミラーの手順)にもありますが、これでもまだ手でやる部分が多いです。
そこで、上の手順をベースに次のスクリプトを作成していい感じに回す事にしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#!/bin/sh if [ $# -eq 2 ]; then PREFIX=$2 else PREFIX="" fi PROJ=`echo "$1" | awk -F "/" '{ sub(/.git/, "", $NF); print $NF}'` curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST -d "{\"name\": \"${PREFIX}${PROJ}\", \"private\": true}" https://api.github.com/orgs/$GITHUB_ORG/repos git clone --bare $1 cd $PROJ.git/ git push --mirror git@github.com:$GITHUB_ORG/$PREFIX$PROJ.git cd .. rm -rf $PROJ.git/ |
ほぼ先に書いた手順を満たしてくれていますが、処理的にはこのような感じです。
- 1つめの引数に渡した移行元Gitリポジトリのリポジトリ名から.gitを除いた分を取得
- 上の名前をベースに新規リポジトリをGitHubに作成(APIv4だとリポジトリの作成ができないようなのでAPIv3を使用)
- ベアリポジトリとして移行元Gitリポジトリをクローン
- クローンしたディレクトリに移動して、移行先リポジトリへ–mirrorでプッシュ
- クローンしたディレクトリを削除
2番目の引数にプレフィックスを付ける事もできるようにしています。
もし実際に実行する際は、GITHUB_TOKENの環境変数にGitHubのPersonal Tokenを、GITHUB_ORGの環境変数にGitHubのOrganization名をセットしてください。Organizationではなく個人アカウントで行う場合は、curlでリクエストするエンドポイントをhttps://api.github.com/user/reposに変更する必要もあります。
また、移行元移行先共にgitコマンドでアクセスできるようになっている必要もあります。
あとは次のように、旧リポジトリの取得先と必要であればプレフィックスの設定をして実行するだけです。
1 |
$ ./script.sh user@example.com/repos/repository.git prefix_ |
ループで回したい場合は次のような感じで一覧を作成し、
1 2 3 4 5 |
user@example.com/repos/repository1.git user@example.com/repos/repository2.git user@example.com/repos/repository3.git user@example.com/repos/repository4.git user@example.com/repos/repository5.git |
whileで回すスクリプトを用意して、それ経由でメインのスクリプトを呼び出すと更に楽になります。
1 2 3 4 5 6 |
#!/bin/sh cat ./list.txt | while read line do ./script.sh $line done |
作業後
旧リポジトリはすぐに読み込みのみにしたい所ですが、移行期間を設けるのを忘れずに。今回は2週間ほど設けました。
その間に、移行のフォローや必要な手順をまとめるなどして、円滑に移行する所までが大事な使命です。
移行期間を過ぎた後もすぐに旧リポジトリ削除までは行わず、Archivedにして読込のみにしています。
おわりに
ということで「GitHubを使い始めたので全部リポジトリ移行してみた」という話でした。
やりたい事はシンプルですが、社内全体に関わるので色々準備やら周知やらが必要で、長い目でスケジュールを見ないといけないですね。(当初は1日で済まそうとしていたので反省も込めて)