サブモジュールとは?
サブモジュール(submodule)は、Gitリポジトリの中に別のGitリポジトリを組み込む仕組みです。外部ライブラリや共有コンポーネントを、独立したリポジトリとして管理しながらプロジェクトに含めることができます。
なぜサブモジュールが必要?
📦 依存関係の問題
- 「共通ライブラリを複数プロジェクトで使いたい」
- 「でもコピペは管理が大変」
- 「npm/composerが使えない環境」
🔒 バージョン管理
- 「外部ライブラリの特定バージョンを固定したい」
- 「ライブラリの更新を制御したい」
🏢 大規模プロジェクト
- 「マイクロサービスを1つのリポジトリで管理」
- 「各サービスは独立して開発したい」
サブモジュールの基本操作
1. サブモジュールの追加
# サブモジュールを追加
git submodule add https://github.com/example/library.git libs/library
# 特定のディレクトリに追加
git submodule add https://github.com/example/auth.git modules/auth
# 追加後の確認
git status
# new file: .gitmodules
# new file: libs/library
2. サブモジュールを含むリポジトリのクローン
# 方法1: クローン後に初期化
git clone https://github.com/myproject/main.git
cd main
git submodule init
git submodule update
# 方法2: 再帰的にクローン(推奨)
git clone --recurse-submodules https://github.com/myproject/main.git
3. サブモジュールの更新
# サブモジュール内で更新
cd libs/library
git pull origin main
cd ../..
git add libs/library
git commit -m "Update library submodule"
# または親リポジトリから更新
git submodule update --remote libs/library
4. サブモジュールの削除
# 1. .gitmodulesから該当エントリを削除
git config -f .gitmodules --remove-section submodule.libs/library
# 2. .git/configから削除
git config --remove-section submodule.libs/library
# 3. インデックスとファイルシステムから削除
git rm --cached libs/library
rm -rf libs/library
rm -rf .git/modules/libs/library
# 4. 変更をコミット
git commit -m "Remove library submodule"
サブモジュールの詳細設定
.gitmodulesファイル
[submodule "libs/library"]
path = libs/library
url = https://github.com/example/library.git
branch = main
[submodule "modules/auth"]
path = modules/auth
url = https://github.com/example/auth.git
branch = stable
特定ブランチの追跡
# サブモジュールを特定ブランチに設定
git config -f .gitmodules submodule.libs/library.branch develop
# 設定したブランチから更新
git submodule update --remote libs/library
よくある使用パターン
パターン1: 共有ライブラリ
# 共通UIコンポーネントをサブモジュールとして追加
git submodule add https://github.com/company/ui-components.git src/shared/ui
# 特定バージョンに固定
cd src/shared/ui
git checkout v2.1.0
cd ../../..
git add src/shared/ui
git commit -m "Pin UI components to v2.1.0"
パターン2: マイクロサービス構成
# 各サービスをサブモジュールとして管理
git submodule add https://github.com/company/auth-service.git services/auth
git submodule add https://github.com/company/api-service.git services/api
git submodule add https://github.com/company/web-service.git services/web
パターン3: ベンダーライブラリ
# パッケージマネージャーが使えない環境での依存管理
git submodule add https://github.com/jquery/jquery.git vendor/jquery
git submodule add https://github.com/twbs/bootstrap.git vendor/bootstrap
サブモジュールの注意点
1. コミットの参照
サブモジュールは特定のコミットを参照します。ブランチではありません。
# サブモジュールの状態確認
git submodule status
# -5d3a3f4a23 libs/library (heads/main-10-g5d3a3f4)
# ↑ コミットハッシュ
2. 変更の追跡
# サブモジュール内での変更は親リポジトリで検出される
cd libs/library
echo "test" > newfile.txt
cd ../..
git status
# modified: libs/library (new commits, modified content)
3. プッシュの順序
# サブモジュールの変更を先にプッシュ
cd libs/library
git push
cd ../..
# その後、親リポジトリをプッシュ
git push
# または一括でプッシュ
git push --recurse-submodules=on-demand
実践演習
CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$
█
ファイルツリー
/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
サブモジュールのベストプラクティス
1. 明確なバージョン管理
# タグを使用してバージョンを明確に
cd libs/library
git checkout v2.0.0
cd ../..
git add libs/library
git commit -m "Update library to v2.0.0"
2. CI/CDでの対応
# .github/workflows/ci.yml
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
3. 開発フローの文書化
# README.md
## サブモジュールの更新方法
1. `git submodule update --remote --merge`
2. 各サブモジュールでテストを実行
3. 親リポジトリでintegrationテストを実行
4. 問題なければコミット
サブモジュールの代替手段
方法 | メリット | デメリット | 使用場面 |
---|---|---|---|
サブモジュール | 独立したバージョン管理 | 複雑な操作 | 大規模プロジェクト |
モノレポ | シンプルな管理 | リポジトリが巨大化 | 密結合なプロジェクト |
パッケージマネージャー | 標準的な方法 | プライベートレジストリが必要 | 一般的なライブラリ |
git subtree | 履歴を統合 | 履歴が複雑化 | 一方向の依存関係 |
まとめ
サブモジュールは強力な機能ですが、チーム全員が使い方を理解している必要があります。適切に使用すれば、大規模プロジェクトの依存関係を効率的に管理できます。
次のレッスンでは、リリース管理に欠かせない「タグとリリース管理」について学びます。