Rails のプラグインを subtree として管理する

(2010.02.05 追記) read-tree する前に ours ストラテジで merge しなきゃダメだったようなので、その手順を追加した。

下のエントリではプラグインを submodule として管理する方法をメモした。
今回扱っているリポジトリは僕だけでなく他社の人 (それも git に慣れてない人) と一緒に弄るものなので、submodule を使うと clone するところから大変なことが分かった *1

そこで、submodule の代わりに subtree merge と呼ばれる方法を採用することに変更した。これは、プラグインリポジトリをブランチの中で管理し、master ブランチへ read-tree というコマンドでマージする方法。

restful_authentication を例に説明する。まず、本家を remote リポジトリとして追加する。

$ git remote add restful-authentication git://github.com/technoweenie/restful-authentication.git

次に、この remote リポジトリを fetch して、restful-authentication ブランチとして checkout する。

$ git fetch restful-authentication
$ git checkout -b restful-authentication restful-authentication/master

そして、master ブランチに切り替えて、restful-authentication ブランチの内容を ours ストラテジでマージしてから vendor/plugins/restful_authentication ディレクトリ以下に読み出す。

$ git checkout master
$ git merge -s ours --no-commit restful_authentication
$ git read-tree --prefix=vendor/plugins/restful_authentication -u restful-authentication
$ git commit -m 'vendor/plugins/restful_authentication: imported'

もし restful-authentication の本家で変更があって、それを自分のリポジトリに反映したければ、restful-authentication ブランチに切り替えて rebase すれば良い。

$ git checkout restful-authentication
$ git rebase restful-authentication/master
...

その変更を自分のリポジトリの master ブランチへマージするときだけ注意が必要で、次のように restful-authentication の変更履歴がマージされないようにする。

$ git checkout master
$ git merge --squash -s subtree --no-commit restful-authentication
$ git commit -a -m 'vendor/plugins/restful_authentication: updated'

参考文献:

*1:submodule は clone と同時には落ちてこないので、clone 後に初期化と更新を手動で行う必要がある。