Git Subtree

git subtreeとは

git subtreeは、外部のgitリポジトリを自分のgitリポジトリのサブディレクトリとしてする仕組み。

使い方

外部のリポジトリを取り込む方法

mainリポジトリとsubリポジトリの二つが存在している。 mainのサブディレクトリとしてsubリポジトリの内容を取り込みたいとする。

ステップ1:mainプロジェクトのremoteにsubリポジトリを登録する
$ git remote add sub-repo https://github.com/example/sub.git
ステップ2:mainプロジェクトにsubリポジトリの内容を取り込む

mainプロジェクトにおいて以下のコマンドを実行する。

$ git subtree add --prefix=lib/sub sub-repo master

実行後、"lib/sub"ディレクトリにsubリポジトリのmasterブランチの内容が取り込まれる。 subtreeの中身の処理としては、subリポジトリのコミットログからなる新規ブランチ(上記の例だとsubリポジトリ)を作成し、そのブランチをマージしている。 そのため、gitのlogにも取り込み先のコミットログが追加される。

リポジトリの更新

subリポジトリの変更を取り込む

外部でのsubリポジトリの更新があった際に、mainに取り込んでいるサブディレクトリの中身を更新する場合。

$ git subtree pull --prefix=lib/sub sub-repo master
subリポジトリに変更を反映する

mainプロジェクト内でsubサブディレクトリを編集し、その変更分をsubのリモートリポジトリにプッシュする場合。 変更分のコミットを行なったのちに以下のコマンドを実行。

$ git subtree push --prefix=lib/sub sub-repo master

"lib/sub"ディレクトリの変更分がsubリポジトリのmasterブランチにプッシュされる。

プロジェクトの一部を切り出す方法

mainプロジェクトの"lib/sub"ディレクトリを切り出して個別のリポジトリとしたい場合。

ステップ1:切り出すディレクトリのコミットログのみを、新しいブランチとして切り出す
$ git subtree split --prefix=lib/sub -b split-sub

このコマンドにより、"lib/sub"ディレクトリ内の変更分のコミットログのみを含んだ"split-sub"という名前のブランチが作成される。

ステップ2:切り出したブランチをリモートリポジトリへプッシュする

切り出したブランチに移動して、取り込み先のリポジトリへプッシュ。

$ git checkout split-sub
$ git push https://github.com/example/sub.git split-sub

参考

・Git Subtree 事始め https://qiita.com/mikakane/items/487ca8b3acddfa5fdb41

・git-subtree移行メモ https://qiita.com/shogo82148/items/04b29b195dbbb373152f