Hugo をインストールしたときに、自分にはあまり馴染みのない git submodule という機能が出てきました。
git submodule は何をするのか?、どういうシチュエーションで役立つのか?、など、大まかに整理しておきたいと思います。
git submodule とは
git submodule は、ある Git リポジトリの中に、別の Git リポジトリを「外部依存」として組み込む仕組みです。
簡単に言うと:
「このディレクトリは、別プロジェクトのリポジトリですよ」と明示的に管理できる機能
です。
何をしているのか?
通常の Git は、1つのリポジトリがすべてのファイルを管理します。
しかし submodule を使うと:
main-project/
├── app/
├── docs/
└── vendor/
└── shared-lib/ ← これが別リポジトリ
この shared-lib は、
- 別の Git リポジトリ
- 独立してバージョン管理される
- main-project からは「特定のコミット」を参照する
という扱いになります。
main-project 側は
「shared-lib のこのコミットを使う」
という情報だけを記録します。
どんな時に役立つ?
共通ライブラリを複数プロジェクトで共有したい場合
例えば:
- 共通ユーティリティライブラリ
- 共通UIコンポーネント
- 社内共通SDK
複数プロジェクトで同じリポジトリを使い回せます。
外部OSSをプロジェクトに組み込みたい場合
例:
- サードパーティ製ライブラリを fork して使う
- 依存ライブラリをソース込みで管理したい
パッケージマネージャを使わず、Gitレベルで依存を固定できます。
リポジトリを分割して管理したい場合
大規模プロジェクトで:
- コアエンジン
- プラグイン群
- ドキュメント
- サンプルコード
を分けたい時にも使われます。
メリット
- リポジトリを独立管理できる
- バージョンを明示的に固定できる
- 依存の履歴が追える
デメリット
- 使い方が少しややこしい
- clone 後に追加操作が必要
git clone --recurse-submodules
または
git submodule update --init --recursive
を実行しないと中身が取れません。
チームメンバーが理解していないと混乱しやすいです。
よくある誤解
submodule は
- 「フォルダ」ではなく
- 「特定コミットを指すポインタ」
です。
親リポジトリが更新されても、submodule は自動では更新されません。
現代的な代替案は?
最近は:
- 言語のパッケージマネージャ(npm / composer / NuGet)
- Git subtree
を使うケースも多いです。
submodule は便利ですが、運用ルールをしっかり決めないと事故ります。
まとめ
submodule とは:
「別リポジトリを、このリポジトリの一部として参照する仕組み」
役立つ場面:
- 共通ライブラリ共有
- 外部コードの組み込み
- リポジトリ分割
ただし:
少しクセが強い機能
のようです。