なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

Git で歴史ごと複数のリポジトリを1つのリポジトリにまとめたい

例えば Node.js モジュールを書いていて、リポジトリ A と B があったとして、それをモノレポ C としてまとめたかったとします。 そういうときはファイルをコピーして新しいリポジトリに入れる方法もありますが、履歴を引き継いだ状態でやりたくなったので、やってみました。

まず、新しいリポジトリを作り、空コミットを打っておきます:

$ git init
$ git commit --allow-empty -m"initial commit"

その後、まとめたいリポジトリをリモートリポジトリとして追加します:

$ git remote add package-a https://github.com/mika-f/package-a.git
$ git remote add package-b https://github.com/mika-f/package-b.git

そして、リモートリポジトリの内容を引っぱってきます。

$ git fetch --all --tags

次に、まずはパッケージA (package-a) へと checkout し、ブランチを作成します。

$ git checkout remotes/package-a/main
$ git checkout -b package-a-main

その後、 package-a/main にいるすべてのファイルが、 packages/a 配下にいたという歴史にします。 それには、次のようなコマンドを使用します:

$ git filter-repo --path-rename :packages/a/ --refs package-a-main --force

このとき、 --refs を忘れてしまうとすべてのブランチの履歴が書き換わるので注意しましょう (わたしはこれで3回やり直しました)。

次に、そのブランチを main へマージします:

$ git checkout main
$ git merge package-a-main --no-ff --allow-unrelated-histories

これで、 package-a の履歴がリポジトリ C へ引き継がれました。 同様の操作 (パッケージ A にチェックアウトからマージまで) を各パッケージに対して行うことで、複数のリポジトリを1つにまとめることが可能です。 お疲れ様でした。