git submoduleとは
git submoduleとは、Gitリポジトリ内に別のGitリポジトリをサブモジュールとして含めることができる機能です。サブモジュールを使うことで、複数のプロジェクトを同時に管理することができます。
例えば、あるプロジェクト内で他のプロジェクトを依存関係として管理する場合などに使用されます。
基本的な使い方
サブモジュールの追加
$ git submodule add [サブモジュールのリポジトリURL]
サブモジュールの初期化
$ git submodule init
# ハッシュコミットの前に「-」がついている場合はサブモジュールを取得できていない
$ git submodule
-[ハッシュコミット] submodule1
$ git submodule update --init
# もしくは
$ git submodule init
$ git submodule update
Cloning into '/Users/Project/submodule1'...
Submodule path 'submodule1': checked out 'ハッシュコミット'
# 取得すると「-」がとれる
$ git submodule
[ハッシュコミット] submodule1 (heads/main)
mainブランチの最新状態を自動追従されるものではありません。
特定のリビジョンを参照するものです。
サブモジュールを含んだリポジトリのクローン
$ git clone --recursive [サブモジュールを含んだリポジトリのURL]
サブモジュールの更新
$ git submodule update
メインプロジェクトでチェックアウトしてもサブモジュールのリビジョンが自動で切り替わってくれないので上記のコマンドが必要になります。
git config --global submodule.recurse true
で自動的にモブモジュールを更新することも可能
mainブランチの最新リビジョンをチェックアウトする
$ git submodule update --remote
# 特定のサブモジュールのみチェックアウトする場合
$ git submodule update --remote [サブモジュール名]
# サブモジュールディレクトリ配下で以下のコマンド実行時と同じ
$ git fetch
$ git merge origin/master
# 最新リビジョンにチェックアウト後に元のリビジョン(親プロジェクトが保持しているリビジョン)に戻りたい場合
$ git submodule update
submodule変更後最新のリビジョンを取り込む
$ git submodule update --remote --merge
--rebase オプションもあります
サブモジュール内に変更を加える場合は、ブランチを切って作業してください。
--merge/--rebaseオプションを忘れると変更が上書きされてしまいます。
メインプロジェクトにpushする
まず、サブモジュールに変更を加えます。
$ cd submodule1
$ git checkout -b feature
$ touch new.txt
$ git add new.txt
$ git commit -m 'add new.txt'
$ git push
サブモジュールに加えたのでサブモジュールのリビジョンは更新されています。
そのため、メインプロジェクトにもサブモジュールのリビジョン変更をpushする必要があります。
$ cd ../
# サブモジュールに更新が入ると「+」がつく
$ git submodule
+[コミットハッシュ] submodule1 (コミットハッシュ)
$ git add submodule1
$ git commit -m 'update submodule1'
$ git push
(サブモジュールをpushしていない場合)pushさせない
--recurse-submodules=checkでサブモジュールのコミットがpushされていない場合、メインプロジェクトのpush時にエラーが表示されます。
$ git push --recurse-submodules=check
The following submodule paths contain changes that can
not be found on any remote:
submodule1
Please try
git push --recurse-submodules=on-demand
or cd to the path and use
git push
to push them to a remote.
fatal: Aborting.
(サブモジュールをpushしていない場合)自動でPushする
git push --recurse-submodules=on-demand
でpushし忘れのサブモジュールもまとめてpushすることが可能です。
$ git push --recurse-submodules=on-demand
追従ブランチの変更
$ git config -f .gitmodules submodule.submodule1.branch feature
$ cat .gitmodules
[submodule "submodule1"]
path = submodule1
url = https://github.com/example/submodule1.git
branch = feature
.gitmodulesの変更を.git/configに反映させる
$ git submodule sync