Git のレポジトリーの中にサブモジュールがあるとき、git submodule update --init --recursive
するとそれぞれのサブモジュールのレポジトリーがローカルにクローンされます。ここで、複数のサブモジュールが同じリモートレポジトリーを参照してゐる1場合、サブモジュールごとに別別にクローンされるので非効率ですよね。といふわけで、同じリモートレポジトリーを一つのローカルレポジトリーにまとめながらクローンするシェルスクリプトを書きました。 git-populate-submodules といふ名前で GitHub に置いてあります。
戦略は、サブモジュールをローカルにクローンしようとする時に先づ ~/.gitclones
といふディレクトリーの中に bare レポジトリーとしてクローンしておいて、その後サブモジュールとなるディレクトリーの中に git worktree add
コマンドを使って作業ディレクトリーを作成します。 ~/.gitclones
の中はサブモジュールの名前2ごとに bare レポジトリーの名前を決める様にすると、同じリモートレポジトリーを参照するサブモジュールが必ず ~/.gitclones
内の同じローカルレポジトリーにクローンされることになります。既にローカルにクローンしたレポジトリーを何度も再クローンしない様に調整すれば完成です3。
スクリプトの冒頭を見れば使ひ方は分かると思ひますが (git submodule update --init --recursive
の代はりに git-populate-submodules -r
を実行すればよいです)、リモートレポジトリーの URL が https://github.com/... の場合はデフォルトで SSH でクローンする様に URL を設定し直すのでご注意4。また既に普通に git submodule update
でクローンしたサブモジュールがある場合はそれらを一旦手動で消す必要があります5。
-
例へば iOS アプリ開発で、Carthage を使って複数のライブラリーを取り込む場合に、どちらのライブラリーにも共通の別ライブラリーへの依存があったりすると、その共通ライブラリーが孫サブモジュールとして合計 2 回取り込まれることになります。 ↩
-
正確には、リモートレポジトリーの URL の最後の部分 ↩
-
といっても、クローン済のものを再クローンしない様にするのは Git がほとんど勝手にやってくれます。 ↩
-
HTTPS よりも SSH の方が筆者の環境では好都合だからといふ個人的な理由による ↩
-
git submodule deinit --all
の後.git/modules
ディレクトリーを消せばよい。(もちろんローカルのサブモジュールだけにあるオブジェクトは失はれる) ↩