Git
Debian

Gitリポジトリが公開されているソフトウェアのDebianパッケージをGitで管理する方法


概要

本稿は、GitHub などの Git リポジトリで公開されているソフトウェアの Debian パッケージを、git-buildpackage パッケージによって提供される gbp コマンドを使って、Git 上で管理する方法のメモです。

前提として、git-buildpackage パッケージの gbp コマンドを使います。また、リモートリポジトリが2つ登場します。


  • 上流リポジトリ: パッケージ対象のソフトウェアが公開されているリポジトリ

  • 管理リポジトリ: 主として debian/ 配下のパッケージ用ファイルを管理する目的のリポジトリ

まだ誤りや勘違いが残っていそうな気がするので、コメントよろしくお願いします。


最初のバージョンのパッケージを作成する時

最初に、空の作業用リポジトリを用意します。

mkdir pkg-sentencepiece

cd pkg-sentencepiece
git init
git commit --allow-empty -m "first commmit"

次に、上流リポジトリをダウンロードします。

git remote add upstream https://github.com/google/sentencepiece.git

git fetch upstream

以下のコマンドで、上流リポジトリに相当する upstream ブランチを作成しておきます。

git checkout -b upstream upstream/master

upstream ブランチは、上流のソースコードを追跡するためのブランチなので、debian/ 配下のパッケージ用ファイルやパッケージ用改変を混入させないように気をつけてください。

パッケージ作成の対象とする upstream ブランチにタグを付与しておきます。タグ名の内、upstream/ は gbp コマンドが使っている固定文字列です。0.0.0+20170516 の部分は、パッケージメンテナが自由に選べるバージョン文字列です。

git tag upstream/0.0.0+20170516

master ブランチに戻って、上流のソースコードをマージします。

git checkout master

git merge --allow-unrelated-histories upstream

debian/ 配下の必要なファイルを作成したり、パッケージ用改変を行います。パッケージが正しく作れるようになるまで、各種ファイルを修正しながら以下のコマンドを繰り返し実行します。

gbp buildpackage

正しく作れるようになったら、以下のコマンドでリリース用パッケージを作成します。このコマンドは、master ブランチ上で、リリース用パッケージに対応するタグも付与します。

gbp buildpackage --git-tag

パッケージ用ファイルとパッケージ用に改変したソースコードなど一式を、管理リポジトリに格納しておきます。

git remote add origin ssh://git@bitbucket.org/tsuchm/pkg-sentencepiece.git

git push -u origin master
git push -u origin --tags


上流の更新に追従する時

upstream ブランチに移動して、上流リポジトリの更新を取得します。

git checkout upstream

git pull

パッケージ対象の上流ソースコードにタグを付与しておきます。

git tag upstream/0.0.0+20170829

master ブランチに戻り、上流ソースコードの更新をマージします。

git checkout master

git merge upstream

必要な改変を行って、パッケージを作成します。


作業用ローカルリポジトリを作り直す時

最初に、管理リポジトリを複製します。

git clone ssh://git@bitbucket.org/tsuchm/pkg-sentencepiece.git

次に、上流リポジトリを追加します。

cd pkg-sentencepiece

git remote add upstream https://github.com/google/sentencepiece.git
git fetch upsteream

上流リポジトリの最新に相当する upstream ブランチを作成しておきます。

git checkout -b upstream upstream/master


上流ソースコードが tarball で公開されている時

本稿の主題とは異なりますが、上流ソースコードが tarball で公開されている場合の git-buildpackage の使い方も、ついでに紹介しておきます。まず、tarball を upstream ブランチに import します。

tar xzf crfsuite-0.12.tar.gz

cd crfsuite-0.12
git init
git commit --allow-empty -m "first commit"
git branch upstream
git checkout upstream
git add *
git commit "Import crfsuite-0.12"
git tag "upstream/0.12"

後は master ブランチに戻って通常のパッケージ作成手順となります。

git checkout master

git merge upstream
dh_make
gbp buildpackage


パッケージが構築できることを自動的に確認する

最近の Git リポジトリサービスでは、継続的インテグレーション(CI)を行うために、git push 後に自動的にコマンドを実行する仕組みがあることが多くなっています。この仕組みを使うと、パッケージがビルドできるかどうか?をチェックすることができます。例として、BitBucket Pipelines を使って、パッケージがビルドできるかどうかをチェックする手順を以下に示します。

まず、以下のようにパッケージのビルド手順を記述した bitbucket-pipelines.yml というファイルを用意します。ここでは、Docker Hub から unstable な debian コンテナをダウンロードし、ビルドに必要なパッケージをインストールしてから、gbp を実行しています。


bitbucket-pipelines.yml

image: debian:unstable

pipelines:
default:
- step:
script:
- apt update
- env DEBIAN_FRONTEND=noninteractive apt upgrade -y
- env DEBIAN_FRONTEND=noninteractive apt install -y build-essential git-buildpackage
- env DEBIAN_FRONTEND=noninteractive apt install -y `perl -ne 's/#.*$//;if(s/^Build-Depends:\s*//){$p=$_;}elsif($p){if(/^\s/){$p.=$_;}else{$p=~s/\(.*?\)//g;$p=~s/[,\s]+/ /g;print $p;undef $p}}' debian/control`
- gbp buildpackage -us -uc


下から2行目の perl を使っているワンライナーは、debian/control ファイルから Build-Depends で指定されているパッケージリストを取り出してインストールしています。なお、単純に全てのパッケージをインストールしようとしますので、アーキテクチャ別の条件分岐や複数のパッケージのどちらかが入っていれば良いなどの論理式を使っている場合は、適切に記述を変更する必要があります。

DEBIAN_FRONTEND 環境変数の設定を行わないと、apt 実行時にエラーになります。また、gbp コマンドに -us オプションと -uc オプションを渡さないと、署名に失敗してエラーになります。

単に bitbucket-pipelines.yml というファイルを置いておくと、debian/ ディレクトリ以外に変更が生じていることになるため、dpkg-source コマンド実行時にエラーになります。そのため、以下のような内容の debian/source/options ファイルを作成しておき、bitbucket-pipelines.yml の変更を無視するようにしておきます。


debian/source/options

extend-diff-ignore = "^bitbucket-pipelines\.yml$"


適切に設定すると、gbp コマンドまで正常に実行される(つまり、パッケージが正常にビルドできる)と、Pipelines の実行結果に Successful と表示されるようになります。