外部リポジトリをプロジェクトに取り込むには、主にGit SubmoduleとGit Subtreeの2つの方法がある。本記事では、両者の違いについて詳しく解説する。
比較まとめ
まず、SubmoduleとSubtreeの主な違いを以下の表にまとめた。
項目 | Git Submodule (リンク方式) | Git Subtree (コピー方式) |
---|---|---|
基本概念 | 外部リポジトリへのリンク(参照)を保持する | 外部リポジトリのファイルと履歴を丸ごとコピーする |
履歴管理 | 親と子の履歴は完全に分離される | 親リポジトリに子の履歴が統合される |
リポジトリサイズ | 最小限(参照情報のみ追加)である | 子リポジトリの分だけ増加する |
クローン時 | git clone --recurse-submodules が必要である |
通常の git clone のみで良い |
更新の取得 | ① submoduleディレクトリに移動 ② git pull |
git subtree pull コマンドを使用する |
変更の反映 | ① submodule内でコミット&プッシュ ② 親リポジトリで更新をコミット |
git subtree push コマンドを使用する |
Git Submodule
親リポジトリ内に、外部リポジトリの特定のコミットを指し示す「ポインター」を置く方法である。履歴は完全に独立している。
メリット 👍
- 親リポジトリの履歴がクリーンに保たれる
- プロジェクトと依存関係の分離が明確である
- 子リポジトリへの変更の反映が簡単である
デメリット 👎
- ワークフローが複雑である(追加コマンドが必要)
- submoduleの更新コミットを忘れやすい
- Git初心者に優しくない
Git Subtree
外部リポジトリのファイルと履歴を、親リポジトリのサブディレクトリに「コピー」する方法である。一度取り込むと親の一部となる。
メリット 👍
- 利用者は特別なコマンドが不要でシンプルである
.gitmodules
のような管理ファイルが不要である- オフラインでも作業可能である
デメリット 👎
- 親リポジトリの履歴が複雑化・肥大化する
- 子リポジトリへの変更反映が少し複雑である
どちらを選ぶべきか?
どちらの方法が適しているかは、プロジェクトの要件やチームのスキルセットによって異なる。
Submoduleが適しているケース
- 外部ライブラリのバージョンを厳密に管理したい場合。
- コードを直接変更せず、定期的な更新が主である場合。
- 親プロジェクトの履歴をクリーンに保ちたい場合。
Subtreeが適しているケース
- プロジェクト利用者の手間を減らしたい場合。
- 外部コードを頻繁にカスタマイズし、親側で管理したい場合。
- シンプルなワークフローを優先したい場合。
まとめ
Gitの依存関係管理はプロジェクトの効率に大きく影響する。Submoduleは依存関係の分離を重視する場合に、Subtreeはシンプルさを求める場合に適している。それぞれのメリット・デメリットを理解し、プロジェクトに合った最適な方法を選択することが重要である。