以前調べたネタですが、ここにメモしておきます。 (最近ブログの更新が滞っていたため)
gitには普通のリポジトリとbareリポジトリがあります。普通のリポジトリは、チェックアウトされたファイルを含むリポジトリで、bareリポジトリは.git
ディレクトリの中身のみを含むリポジトリです。
bareリポジトリは、
% git init --bare hoge
のように作ります。サーバにbareリポジトリを作って、そこにみんなでpushするような使い方は一般的でしょう。ちなみに、push先がbareリポジトリではなかったりすると、ワーニングがでたりします。
さて、例えば2つのチームがそれぞれ別々のリモートサーバを使って別のbareリポジトリにpushしていたとします。その2つのbareリポジトリを同期したいとします。bareリポジトリにはチェックアウトという概念がないので、git merge
は使えません。
マニュアルには直接的な説明は見つからなかったのですが、結局次のようにすればできることが分かりました。
% git fetch origin 'refs/heads/*:refs/heads/*'
これを一方のbareリポジトリで実行すると、originで指定された他方のリポジトリの差分を取り込むことになります。上記例では全てのブランチを取得していますが、例えばmasterのみを同期するには、
% git fetch origin 'refs/heads/master:refs/heads/master'
とします。同期と書きましたが、双方向に同期する場合はpushする必要があります。
もう一つの注意点は、マージをするわけではないので、fast-forwardが基本です。fast-forwardできない場合は失敗するでしょう。マニュアルによると'+'を先頭につけておくとマージしてくれるようですが、コンフリクトした場合にどうなるかはよく分かりません。
ご参考まで
追記。
双方がpushし合う場合は、この方法は必要ではありません。この方法が必要になるのは、一方のbareリポジトリがファイアウォールの内側にあるなど、双方にpushできない場合です。
コメント