はじめに
gitbucketはインストールが簡単なGitプラットフォームです。Scalaで開発されており、高い拡張性とGitHub API互換APIを備えています。
インストールは「gitbucket.war」ファイルをダウンロードしてJava実行するだけで動作します。
gitbucketのインストール自体はこのあたりを参考に構築します。
今回、gitbucket上でrepoコマンドを使ってビルドツリーを構築しようとした時にハマったポイントの
回避方法を紹介します(もっといい方法があるよ!というコメントを頂ければ嬉しいです)。
課題内容
gitbucket上のリポジトリを集めるためのマニフェストファイルを書いてrepo init -u http://hostname/manifest
& repo sync
としてみたら
$ repo init http://mygitbucketserver:8080/git/PUBLIC/manifest.git -m sample.xml
$ repo sync
my_repository:
fatal: Couldn't find remote ref refs/heads/master
my_repository: sleeping 4.0 seconds before retrying
fatal: Couldn't find remote ref refs/heads/master
とエラーで失敗します。各リポジトリを個別にgit clone
すると当然成功するので、repoで取得するときだけ発生する問題です。
色々と調べてみるとここらへんの話題が見つかりました。
- Handling of improper URL since 4.31.0 (missing .git) #2342
- Support repository URL format for old Git clients that are not adding .git suffix
どうやら、一部のgitクライアント(repoを含む)ではリポジトリURLの最後に.git
サフィックスを付けずにgit cloneを実行しようしています。そして、git server側もそれに対応するために.git
無しのURLでアクセスしてきた場合に.git
付きURLへリダイレクトする機能があります。(githubは対応)
しかし、gitbucket(というかどうやらgitbucketが採用しているgitの実装jgit)ではリダイレクトをやめてしまったようです。(「ようです」と言うのは、調査の時にissuesで「リダイレクト機能は本来の仕様とは異なる、repoコマンドのバグにあわせる必要はない。」というやり取りを見たのですが、そのリファレンスを失念してしまいました。)
repoの修正
ということで、repoコマンドの不具合箇所を修正しました。
def ToRemoteSpec(self, projectName):
fetchUrl = self.resolvedFetchUrl.rstrip('/')
- url = fetchUrl + '/' + projectName
+ url = fetchUrl + '/' + projectName + '.git'
remoteName = self.name
if self.remoteAlias:
remoteName = self.remoteAlias
return RemoteSpec(remoteName,
ローカルのrepoコマンドの実行
通常、repoコマンドを実行したときrepoモジュールのリポジトリ(https://gerrit.googlesource.com/git-repo)からrepoモジュールをダウンロードしてから実行します。自前のrepoモジュールを使うときには repo init
に引数 --repo-url
でrepoのリポジトリURLを指定します。
$ repo init --repo-url http://mygitbucketserver:8080/git/PUBLIC/repo.git
repoモジュールをダウンロードする際に署名されているかどうかをチェックします。ローカルリポジトリの署名をしていない場合は warning: 'refs/heads/stable' is not signed; falling back to signed release 'v2.22'
となって、修正したモジュールが使用されません。「git作業内容への署名」に従って署名すればワーニングは消えると思いますが、今回は信頼できるローカルサーバーからのダウンロードだという前提で、--no-repo-verify
オプションを付与して署名検証を無効にします。
また、ローカルリポジトリでbundleファイルを作成していないので、--no-clone-bundle
オプションも追加します。
$ repo init --repo-url http://mygitbucketserver:8080/git/PUBLIC/repo.git \
-u ttp://mygitbucketserver:8080/git/ATMOBI_PKG/manifest.git \
-m develop_3.0_2d.xml --no-clone-bundle --no-repo-verify
毎回--repo-url
オプションを付与するとコマンドが長くなるので、環境変数REPO_URL
を設定しておくとコマンドラインでの指定を省略できます。
$ export REPO_URL=http://mygitbucketserver:8080/git/PUBLIC/repo.git
$ repo init -u ttp://mygitbucketserver:8080/git/ATMOBI_PKG/manifest.git \
-m develop_3.0_2d.xml --no-clone-bundle --no-repo-verify
おわりに
gitbuketの issues #2342 が対応されたら不要になると思いますがそれまでの対策になれば幸いです。
他に回避方法ご存知かたがいらっしゃればコメントお願いします。