Git SubmoduleとGit Subtreeによるベースプロジェクトの変更取り込み
Git Subtreeはエラーが出ているので確認中
ベースの開発プロジェクトを一つのリポジトリで管理し、それを利用する複数の個別プロジェクトを別のリポジトリで管理しつつ、ベースの変更を取り込む方法として、主にGit SubmoduleとGit Subtreeの2つがあります。
1. Git Submodule(サブモジュール)方式
ベースプロジェクトを外部の依存関係として扱い、バージョンを固定しながら使用したい場合に適しています。
💡 構成のイメージ
- 親リポジトリ(個別プロジェクト)が、ベースリポジトリの特定のコミットへの**参照(ポインタ)**を保持します。
- ベースコードの履歴は親リポジトリから隔離されています。
🚀 手順
1-1. ベースリポジトリの作成
ベースの開発プロジェクトを独立したリポジトリとして作成・管理します。
1-2. 個別プロジェクト(親リポジトリ)からのサブモジュール追加
個別プロジェクトのリポジトリ内で、ベースリポジトリをサブモジュールとして追加します。
# 個別プロジェクトのルートディレクトリに移動
cd project-a
# ベースリポジトリをサブモジュールとして追加
# 'base' は親リポジトリ内でベースコードを配置するディレクトリ名
git submodule add <ベースリポジトリのURL> base
# .gitmodules ファイルと 'base' ディレクトリの参照をコミット
git add .
git commit -m "Add base project as a submodule"
git push
1-3. ベースの変更を取り込む(Pull)
ベースリポジトリに変更が入った後、その変更を個別プロジェクトに取り込む手順です。
-
サブモジュール内での更新: サブモジュールディレクトリに移動し、最新のコードを取得します。
cd base git pull origin main cd .. -
親リポジトリでの参照の更新: 親リポジトリに戻り、サブモジュールが新しいコミットを参照するように参照情報をコミットします。
git add base git commit -m "Update base submodule to the latest commit" git push
2. Git Subtree(サブツリー)方式
ベースプロジェクトをリポジトリの一部として扱い、Git操作をシンプルにしたい場合に適しています。
💡 構成のイメージ
- ベースリポジトリの内容が、親リポジトリ内の通常のサブディレクトリとしてファイルそのものとして統合されます。
- ベースコードの履歴は、親リポジトリの履歴に組み込まれます。
🚀 手順
2-1. ベースリポジトリの追加(Subtreeの初期設定)
個別プロジェクト(親リポジトリ)内で、ベースリポジトリをリモートとして追加し、内容をサブディレクトリに統合します。
# 個別プロジェクトのルートディレクトリに移動
cd project-a
# ベースリポジトリをリモートとして一時的に追加
git remote add base-remote <ベースリポジトリのURL>
# ベースリポジトリの内容を 'base' ディレクトリに統合
# --squash: ベースの履歴全体を一つにまとめてコミットとして追加します
git subtree add --prefix=base base-remote main --squash
# 親リポジトリにコミットし、プッシュ
git push
2-2. ベースの変更を取り込む(Pull)
ベースリポジトリに新しい変更が入った後、その変更を個別プロジェクトに取り込む手順です。
-
subtree pullコマンドを実行するだけで、ベースリポジトリの最新の変更をbaseディレクトリに自動でマージできます。
# 親リポジトリのルートディレクトリにいることを確認
# ベースリポジトリの最新の変更を 'base' ディレクトリに取り込みマージ
git subtree pull --prefix=base base-remote main
# 親リポジトリの変更をプッシュ
git push
2-3. 個別プロジェクトの変更をベースに反映する(Push)
もし個別プロジェクト側でベースコードに変更を加えた場合、それをベースリポジトリ本体に反映させることも可能です。
# 'base' ディレクトリ内の変更をベースリポジトリにプッシュ
git subtree push --prefix=base base-remote main
🆚 SubmoduleとSubtreeの使い分け
| 項目 | Git Submodule | Git Subtree |
|---|---|---|
| 用途 | 外部ライブラリや共通依存としてバージョンを固定したい。 | プロジェクトのサブセットとしてシンプルな構造にしたい。 |
| クローン |
git clone --recurse-submodules が必要。 |
git clone のみで完了。 |
| 履歴 | 親とベースの履歴は分離される。 | ベースの履歴が親に統合される。 |
| 複雑さ | Gitの概念(外部参照)がやや複雑。 | コマンドは複雑だが、構造は通常のディレクトリと同じ。 |
| 推奨 | ベースのコードを変更することが少ない、または厳密にバージョン管理したい場合。 | ベースのコードを頻繁に変更する可能性があり、シンプルさを優先したい場合。 |