あるレポジトリのサブディレクトリ配下を別のレポジトリへ履歴付きで移行する - $shibayu36->blog; の逆バージョン。
あるレポジトリでずっと開発していたが、やっぱりモノレポの中に入れたいとなって、履歴付きでモノレポの特定のサブディレクトリ配下に移動したい時があった。たとえば https://github.com/shibayu36/go_todo_app の履歴をすべて https://github.com/shibayu36/go-playground のgo_todo_appディレクトリに移したいみたいなケースだ。この時コミット履歴としてはgo-playgroundのgo_todo_app/配下で初めから開発していたかのように移したい。
この解決策として Gitのサブツリーのマージについて - GitHub Docs にあるように、サブツリーマージという方法も取れる。しかしこちらは履歴的にはレポジトリルートで開発した後にgit mvでサブディレクトリに移したような履歴になってしまう。これだとgit logなどで変更を追いかけづらい。
そこで今回もgit filter-repoを使って移動する。作戦としては
- go_todo_appレポジトリ側で、go_todo_app/ディレクトリで開発しているような履歴に変更する
- go-playgroundレポジトリのremoteとしてgo_todo_appレポジトリを追加し、mergeコミットを作ってサブディレクトリ配下で開発していたような履歴を作る
ではやってみよう。まずはgit-filter-repoを入れておく。
brew install git-filter-repo
続いて、go_todo_appレポジトリ側で、go_todo_app/ディレクトリで開発しているような履歴に変更する。git filter-repoの--to-subdirectory-filterを使うと簡単にできる。
git clone git@github.com:shibayu36/go_todo_app.git cd go_todo_app git filter-repo --to-subdirectory-filter go_todo_app cd ..
さらにgo-playgroundへgo_todo_appレポジトリの履歴をマージする。
git clone git@github.com:shibayu36/go-playground.git cd go-playground git remote add go_todo_app ../go_todo_app # localのディレクトリをremoteとして追加 git fetch go_todo_app main # --allow-unrelated-historiesを使うことで別の履歴をマージできる # --no-ffを使ってマージコミットを確実に作る git merge --allow-unrelated-histories --no-ff go_todo_app/main git push origin main
これで完了。go-playgroundレポジトリの履歴は こちらのようになり、さらにhttps://github.com/shibayu36/go-playground/commits/main/go_todo_appを見るとgo_todo_app/サブディレクトリ配下で初めから開発していたような履歴になっている。