Mercurialで別オリジンのリポジトリ間の同期を取る運用の仕方について
前説
DjangoでWebアプリを開発していて自分はJavaScript部分を担当しています。
で、サーバ側を動かさないと開発できないのは辛いので、
サーバサイドで生成されたHTMLとJSONをwgetして、js/dummy/とかに配置し、
各種URLの参照を書き換えてローカルでJavaScriptだけもりもり実装できるようにしました。
サーバサイドの実装に先行してJavaScriptの実装を進めていたため、
プロジェクト全体(django-apps)と独立してバージョン管理したかったため、
static配下だけが入ったdjango-staticというリポジトリを作成し、
そちらで開発を進めていきました。
今回の話は、プロジェクト全体(django-apps)とJavaScript&CSSだけ(django-static)の
二つのリポジトリの同期をとって運用していく話です。
準備
hg clone django-apps hg pull django-static
とやると
「abort: repository is unrelated」と出てpullに失敗してしまいます。
hg pull -f django-static
とやればpull出来るので、2つのオリジンを持つリポジトリが出来上がります。
それぞれのdefaultのheadにdjango-apps-head,django-static-headというlocal tagを打って、
今後は随時移動していくことにしましょう。
同期をとる方法
revert
同期したいのは特定のディレクトリ(今回はstatic)だけなのでrevertを使うのもありです。
hg update django-apps-head hg revert static/ -r django-static-head hg commit -m "message"
とやればdjango-static-headの成果を持ってくることができます。
ただし、細かい履歴が消えてしまう、django-apps側に変更があっても上書きされてしまうなどの難点があります。
transplant
hg transplantは任意のchangesetを任意の位置に移植できます。
なのでサブセットの方から更新分のchangesetsを移植するのは簡単です。
hg pull django-static hg update django-apps-head hg transplant pullしてきた中で一番古いrevision番号:tip
とかやれば、簡単に同期できます。
後はdjango-appsにそのままpushしてもよし、
人に見せる用に適度にcommit圧縮してからpushするもよしです。
重要なのはstatic配下が同じ状態のそれぞれのrevisionがどこか記録しておくことです。
django-apps-head,django-static-headを適切に移動しておきましょう。
django-apps→django-staticの方向の同期はやや難しいです。
というのも、static配下の変更を含むchangesetがstatic配下以外への変更を含まないとは限らないからです。
Djangoの場合だとtemplates配下とセットで変更されていることが多いです。
例えばstatic/js/hoge.jsとtemplates/index.htmlが変更されているとして、
そのchangesetをdjango-staticの方にtransplantすると、
static/js/hoge.jsの差分は適用できますが、templates/index.htmlの差分を適用できずに、
transplantは中断してしまいます。
templates/index.htmlの適用できなかった差分はtemplates/index.html.rejとして保存されます。
本来のtransplantのフローでは適用できなかった差分を手動で適用し、
rejファイルを削除し、
hg transplant --continue
とやってtransplantを完了させます。
今回はstatic配下の変更以外は全く要らないので、こんな感じでいいでしょう。
hg transplant static配下の変更を含むrevision find . -name "*.rej" | grep -v -P '\./static' | xargs rm hg transplant --continue
対象になるchangesetsを全部移植し終えたらlocal tagを移動した上で、
static配下が同一であるか確認しましょう。
ファイル内容が同一なだけなので、hg statusではダメです。
hg diff static/ -r django-apps-head:django-static-head