git submoduleとは
gitで管理しているリポジトリに別リポジトリを連携させる機能です。
このリポジトリのコードを動かすときに必要なリポジトリをクローンしてくださいを自動化できます。
しかし、システム開発途中で起こることとして、親のリポジトリ更新に合わせて、サブモジュール側にも変更が必要になるパターンです。
本来は、サブモジュールで読み込むリビジョンは安定版を使用して、その基盤の上に新規コードを作っていくのが良いとは思いますが、新規機能の追加などでそうも言っていられないことがあります。
なので、この記事ではサブモジュールに変更を加える際に利用するコマンドを説明します。
ますは、テストリポジトリの作成
まず、test_main
, test_a
, test_b
の3つテストリポジトリを立てて、test_a
, test_b
をtest_main
のsubmoduleに設定します。
./test_main
├── README.md
├── test_a # submodule
│ └── README.md
└── test_b # submodule
└── README.md
test_main
をクローンしてから、サブモジュールを作成するまでの手順は以下です。
$ git clone git@github.com:wakaba130/test_main.git
$ cd test_main/
$ git submodule add git@github.com:wakaba130/test_a.git
$ git submodule add git@github.com:wakaba130/test_b.git
$ ls
README.md test_a test_b
この状態でいったんコミットします。
$ git add .
$ git commit -m "add submodule"
[main ace8afe] add submodule
3 files changed, 8 insertions(+)
create mode 100644 .gitmodules
create mode 160000 test_a
create mode 160000 test_b
$ git push origin main
# もろもろの表示省略
To github.com:wakaba130/test_main.git
b056e33..9e05be5 main -> main
※ コミットする時に以下のようにエラーが出た場合は、Run
以下の2行のコマンドにより、
メールアドレスとユーザー名を設定してください。
*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
fatal: empty ident name (for <---@---.>) not allowed
ブラウザでgithubを確認して、以下のようになっていたらOK
ここからが本題
では、このサブモジュールに加えた変更をコミットするにはどうするのかやっていきたいと思います。
まず、サブモジュールにpushすると現在のブランチに直接プッシュして変更してしまうため、サブモジュール側に新しいブランチを切って、そちらにコミットします。
# サブモジュールのチェックアウト
$ git submodule foreach git checkout -b develop
# test_mainのブランチのチェックアウト
$ git checkout -b develop
コマンド解説
リポジトリ内にサブモジュール (submodule)が複数あり、各サブモジュールで同じコマンドを実行したい場合にforeachを使用します。
$ git submodule foreach <コマンド>
変更を加えた後のコミット&プッシュ
test_a
とtest_b
のREADME.mdを以下のように変更しました。
# test_a
developブランチに変更しました。
# test_b
developブランチに変更しました。
変更した結果をforeach
を使用してコミット&プッシュします。
# サブモジュールに対するコミット&プッシュ
$ git submodule foreach git add -A
$ git submodule foreach git commit -m 'submodule commit'
$ git submodule foreach git push --set-upstream origin develop
# test_mainリポジトリに対するコミット&プッシュ
$ git add -A
$ git commit -m "submodule commit"
$ git push origin develop
あとは、各サブモジュールでプッシュしたブランチをメインブランチにマージしたりする。
submoduleの参照するコミットを変更する
サブモジュール側を変更しても、サブモジュールを参照している親側は自動で変更されません。
サブモジュールで紐づいているのは、コミットIDであり、ブランチではないからです。
そのため、変更後のコミットIDを参照するように変更する必要があります。
# サブモジュールのディレクトリに移動
$ cd test_b
# 必要なバージョンをチェックアウトする
$ git checkout <コミットID>
# 親側に移動
$ cd ../
# 親側でコミット
$ git add .
$ git commit -m "revision test_b"
submoduleを含んだクローン
サブモジュールを使用しているリポジトリをクローンする際には、--recursive
オプションを付ける必要があります。
$ git clone --recursive git@github.com:wakaba130/test_main.git
--recursive
を付け忘れた場合は、以下のコマンドでサブモジュールが読み込めます。
$ cd test_main
$ git submodule update --init
まとめ
サブモジュール側に変更があった際に使用するコマンドをまとめました。
今後の業務などで他にも覚える必要のあるコマンドが出てきたら更新します。
参考