In a nutshell
Git の subtree
を用いる事で,外部リポジトリを履歴ごと指定ディレクトリに取り込むことができ,モノレポ化に適している.
しかも submodule
より扱いやすく,取り込み後に外部リポジトリを削除しても問題ない
はじめに
今まで,個人で使用しているリポジトリは,プロジェクトと1対1で対応させていた.しかし,リモートリポジトリが多くなった為,一元管理したいと考えて,モノレポ化する事とした.各プロジェクトでのコミットメッセージや履歴を適切に,新規リポジトリに引き継ぐ為に調べた事の1つが subtree
である.これについて,学びの記録として以下に纏めた.
予想される読み手
- Git について初学者であり,学びたい
- 今後も Git を利用していく予定がある
- 今後,モノレポとポリレポを使い分けるかもしれない
事前知識
リポジトリとは
Git における「リポジトリ(repository)」とは,ソースコードやそれに関連するファイルの履歴を保存・管理する場所.開発の進捗(コミット履歴)を記録し,変更の追跡や過去の状態への復元を可能とする.ローカルに作成できるものと,GitHub などのサービス上にあるリモートリポジトリがある.
モノレポとポリレポについて
-
モノレポ(monorepo):複数のプロジェクトやパッケージを,1つのリポジトリで一元管理する方式.
管理が一貫しやすく,変更の追跡や依存関係の確認がしやすいメリットがある. -
ポリレポ(polyrepo):各プロジェクトを個別のリポジトリで管理する方式.
分離性が高く,それぞれのプロジェクトが独立しているため,チームや責務ごとに管理しやすい特徴がある.
目的
- 外部リポジトリの 履歴も含めて 取り込む(履歴の保持が重要)
- 自分のリポジトリ(メイン)に取り込んで モノレポ化 したい
- 取り込んだ後は,外部リポジトリは 不要になる(削除OK)
- 外部リポジトリの内容は,サブディレクトリとして取り込みたい(例:
external_repo/
)
最適な方法:git subtree
git subtree
は,外部リポジトリの履歴を保持したまま,自分のプロジェクトの一部として統合できる Git のコマンド.したがって,外部リポジトリを指定したサブディレクトリに取り込み,履歴も保持できる.しかも submodule
と違い,独立して管理でき,取り込んだ後は削除してOK.
なぜ git subtree
なのか
外部リポジトリの履歴(コミットログなど)を保持できる.
コミットログは .git
フォルダに保存されており,リポジトリと1対1で対応している.よって,単にデータをコピーしても,履歴は引き継げない.
手順(例:external_repo
という名前のサブディレクトリに取り込む)
# 1. 自分のモノレポのリポジトリに移動
cd your-main-repo
# 2. 外部リポジトリをリモートとして追加(名前は何でもよい)
git remote add external_repo https://github.com/ユーザー名/外部リポジトリ.git
# ※リモート名は一意である必要がある為,external_repo,を複数作成しないように
# 3. 外部リポジトリのデータを取得(fetch)
git fetch external_repo
# 4. 外部リポジトリの履歴を指定ディレクトリに subtree としてマージ
git subtree add --prefix=external_repo external_repo/main --squash
# ↑ブランチ名が main でない場合は変更する
# --squash を外せば履歴を詳細に残す(全履歴保持)
# --squash を使えば1つのコミットとしてまとめる(軽量化)
# -> 外部履歴が煩雑な場合や,最初だけ取り込みたい場合に有効
取り込み後にやること(外部リポジトリ削除)
# もう外部リポジトリはいらない場合
git remote remove external_repo
補足
subtree
のメリット
-
submodule
と違い,clone したときに追加設定が不要 - 履歴が保持される(--squash を使わなければフルログ)
- 将来,
subtree pull
やpush
で同期も可能(今回は削除予定なので不要)
必要なら,git subtree split
により,モノレポの一部を新たなリポジトリとして切り出すことができる.例えば,再びポリレポに戻したい場合などに活用できる.
他の方法について : subtree pull
, pull
将来的に外部リポジトリと連携を続けたい場合は,git subtree pull
や push
を使って同期を行うこともできる.
Summary
- モノレポ化のために
git subtree
を使うと,履歴を保持したまま外部リポジトリを統合できる. -
--prefix
でサブディレクトリを指定し,外部の内容を整理して取り込める. -
--squash
オプションで履歴を1つのコミットにまとめることも可能. - 取り込み後は外部リポジトリの削除や管理の簡略化が可能.
- 将来的に分離したければ
subtree split
により再分離も可能.