Git submodule とは?
submodule は、あるリポジトリの中に特定のコミットに固定してネストされたリポジトリであり、外部コードを取り込みつつその正確なバージョンを追跡できるようにします。
submodule は、ある Git リポジトリが別のリポジトリをサブディレクトリとして、特定のコミットにロックした状態で含められるようにします。共有ライブラリやコンポーネントを再利用しつつ、その履歴を分離しバージョンを明示的に保つ方法です。submodule は強力ですが、初心者を驚かせることで知られています。
submodule の仕組み
親リポジトリは submodule のファイルではなく、その特定のコミットへのポインタを保存します。submodule は独自の履歴を持つ独自のリポジトリに存在します。親を特定のコミットでチェックアウトすると、記録された submodule のコミットが、ネストされたコードのどのバージョンを使うべきかを正確に示します。
submodule の追加と更新
submodule を追加し、それを初期化して更新することで、固定されたコミットの内容を取得します。
git submodule add https://github.com/owner/lib.git vendor/lib
git submodule update --init --recursiveなぜ扱いにくいのか
submodule は一般的なワークフローに手順を追加します。単純な clone は親を取得しますが、初期化するまで submodule は空のままです。submodule のポインタの更新は、親における別のコミットになります。これらの手順を忘れると、ファイルの欠落や古い依存関係につながり、混乱の頻繁な原因となります。
CI/CD における submodule
CI のチェックアウトは submodule を取得するよう指示する必要があり、そうしないと build はコードの欠落で失敗します。ほとんどのチェックアウト action は、必要なら再帰的に submodule を取得するオプションを公開しています。各 submodule は独自の clone であるため、チェックアウト時間が増えます。build が本当にそれらに依存する場合にのみ取得しましょう。
submodule の扱い方
- 親を clone した後に submodule を初期化して更新しましょう。
- submodule のポインタを進めたら親にコミットしましょう。
- CI で submodule のチェックアウトを有効化しないと build にファイルが欠けます。
- よりシンプルな再利用のためにパッケージマネージャーなどの代替手段を検討しましょう。
重要なポイント
- submodule はあるリポジトリを別のリポジトリの中に、コミットに固定してネストします。
- 単純な clone では、初期化するまで submodule は空のままです。
- CI は submodule を取得するよう明示的に有効化しないと、build にそのコードが欠けます。