複数のリポジトリをモノレポ化する (multirepo to monorepo)
TL;DR
- 複数のリポジトリをモノレポ化した際の備忘録
- tomono スクリプトを修正したスクリプトを使用
- リポジトリを移行することにフォーカスした記事
- 以下の内容はこの記事では扱わない
- モノレポ自体の説明や移行の検討
- CI/CD、ツールなど
- 運用ルール
- サンプルのリポジトリを公開してるのでお試し可能
目次
概要
移行前

移行後
- リポジトリ:monorepo
- ModuleAフォルダ
- READMEほか
- ModuleBフォルダ
- READMEほか
- ModuleCフォルダ
- READMEほか
- ModuleDフォルダ
- READMEほか
- ModuleAフォルダ

手順
1. 移行するものを決める
- HEADのファイル、履歴、Git LFSファイル
- タグ
- ブランチ
- issue
- プルリク
今回は以下を移行対象とした
- 履歴
- Git LFSファイル
- タグ
- ブランチの一部
2. 新しいリポジトリを作る
新しいリポジトリを作成する。リポジトリの設定など必要な情報を引き継ぐ。
3. 準備
作業ディレクトリを作成する。
tomono リポジトリから以下のファイルを作業ディレクトリに保存する。
- tomono
- tomono.pushall
- tomono.removeremotes
以下の内容を repos.txt という名前で作成する。
[git@github.com](mailto:git@github.com):yotiky/monorepo-test.ModuleA.git ModuleA [git@github.com](mailto:git@github.com):yotiky/monorepo-test.ModuleB.git ModuleB [git@github.com](mailto:git@github.com):yotiky/monorepo-test.ModuleC.git ModuleC https://github.com/yotiky/monorepo-test.ModuleD.git ModuleD ModuleD lfs
4. リポジトリを移行する
以下の内容を順に実行していく。
export MONOREPO_NAME=Monorepo export MONOREPO_BRANCHES="main|branch-3$|^ModuleD" ./tomono < repos.txt cd Monorepo git remote add origin git@github.com:yotiky/monorepo-test.monorepo.git ../tomono.removeremotes < ../repos.txt ../tomono.pushall ../merged_branches.txt
5. 検証
- ブランチの作成、プルリク、マージが行えるか
git lfs fetch --allでGit LFSのチェック- アプリなどの動作確認
補足
サンプルリポジトリ
tomono スクリプト
- 異なるリポジトリの同じ名前のブランチは1つにマージされる
- 例) ModuleA/main、ModuleB/mainは、origin/mainにマージ
- タグはリポジトリ名で名前空間毎に割り振られる
- 例) ModuleA/release1、ModuleB/release1
- LFSを使ってる場合はSSHではなくHTTPSのアドレスを指定する
repos.txtは最後に空行が必要MONOREPO_BRANCHESは正規表現が使える"main|develop"- mainまたはdevelopブランチのみ"release.*"- releaseで始まる全てのブランチ".*"- 全てのブランチ
注意点
フィーチャーブランチ
フィーチャーブランチなど、ブランチを複数持っていく場合は、移行後のリポジトリでマージのコンフリクトが発生するので注意する必要がある。
移行前に最新にしていたとしても、移行の過程で各ブランチにファイルを追加、移動するコミットが入ることになる。フィーチャーブランチで変更していたものは基本的に衝突することになる。
ファイルの削除やリネームを行っていた場合、コンフリクトの解消では解消できないのでより注意が必要である。マージしようとした時にフィーチャーブランチでファイルを削除していたとしても、そもそも移行すること自体がファイルの追加であるため、追加されていないファイルを削除することができない状態となるようだ。一度追加したmainブランチで解消した上で削除するなどする必要があった。(Fork上)

できる限り少ないブランチを対象にすることをおすすめする。
Git LFSファイル
今回修正したスクリプトは、git lfs push する時にブランチを指定している。
ブランチに関わらずすべてのLFSファイルを引っ越したい場合は、元のリポジトリに新リポジトリをremoteとして追加して、git lfs push <新リポジトリ> --allして、新リポジトリ側にPUSHしてしまうのが良いだろう。
移行元リポジトリでLFSをPUSH
手順の新しいリポジトリを作成した後に、移行元のリポジトリ、今回だとModuleDで以下の作業を実施する。
git lfs fetch --all git remote add monorepo git@github.com:yotiky/monorepo-test.monorepo.git git lfs push monorepo --all git remote remove monorepo
サンプルリポジトリ
- yotiky/monorepo-test.ModuleA
- yotiky/monorepo-test.ModuleB
- yotiky/monorepo-test.ModuleC
- yotiky/monorepo-test.ModuleD
サンプルシナリオ
ModuleA~D


Monorepo
