サブモジュールを使ったリポジトリ間の共通パーツ管理
目的
共通ソースを効率的に管理
下記で、repository1内のcommonとrepository2内のcommonは全く同じ。
このようなケースではソース管理をどうするのがよいだろう?
その一つの手段としてサブモジュール管理が有効。
Project
├── repository1
│ └── app
│ ├── common
│ ├── ...
│ └── ...
└── repositpry2
└── app
├── common
├── ...
└── ...
手順
1. 共通パーツ(common)を新規にリポジトリに切り出す。
共通パーツ(common)は個別のリポジトリで管理したほうが楽なので、commonリポジトリを新規作成。
ここで、作成されるリポジトリのURLをxxxxx@○○○○○.git.backlog.com:common.git
とする。
2. repository1,repository2から共通パーツ(common)を削除
repository1,repository2では共通パーツ(common)をソース管理したくないので、
repository1/app/commonとrepository2/app/commonを一旦削除。
共通パーツ(common)をサブモジュールとして追加
repository1に追加
Project$ cd repository1
Project/repository1$ git submodule add xxxxx@○○○○○.git.backlog.com:common.git app/common
repository2に追加
Project$ cd repository2
Project/repository2$ git submodule add xxxxx@○○○○○.git.backlog.com:common.git app/common
上記により、以下のファイルが自動で生成・編集される。
repository1/.gitmodules
[submodule "app/common"]
path = app/common
url = xxxxx@○○○○○.git.backlog.com:common.git
repository2/.gitmodules
[submodule "app/common"]
path = app/common
url = xxxxx@○○○○○.git.backlog.com:common.git
repository1/.git/config
...(省略)
[submodule "app/common"]
active = true
url = xxxxx@○○○○○.git.backlog.com:common.git
repository2/.git/config
...(省略)
[submodule "app/common"]
active = true
url = xxxxx@○○○○○.git.backlog.com:common.git
サブモジュールの最新化
共通パーツ(common)リポジトリに修正が入った場合は、repository1とrepository2のサブモジュールを最新化しなければならない。
repository1のcommonを最新化したいときは、Project/repository1ディレクトリに移動して以下を実行。
repository2のcommonを最新化したいときは、Project/repository2ディレクトリに移動して以下を実行。
$ git submodule update --init --recursive
差分について
repository1やresository2では、以下のようにapp/commonが差分として認識されますが、ここではサブモジュールのコミットポインタが5aa0e5f20b79f49e9022f8df95823c597d1401eb
のような形で記録されます。
もし、コミットポインタが古ければ最新のコミットポインタに更新。
git submodule update --remote --merge
上記のコマンドで、サブモジュールのリモートリポジトリから最新の変更をフェッチし、サブモジュールをそのリモートの最新コミットに更新できます。
コミットポインタの差分をpushして完了です。
追記
サブモジュールの参照は相対パスでもできるので、たびたび修正が発生する共通パーツであれば、相対パスを使ったほうが楽。
Project
├── repository1
│ └── app
│ ├── common
│ ├── ...
└── ...
├── repositpry2
│ └── app
│ ├── common
│ ├── ...
│ └── ...
└── common
repository1にサブモジュール追加
Project/repository1$ git submodule add ../common.git app/common
repository2にサブモジュール追加
Project/repository2$ git submodule add ../common.git app/common
[submodule "app/common"]
path = app/common
url = ../common.git
[submodule "app/common"]
path = app/common
url = ../common.git
Discussion