Git の sparse checkout を活用したモノレポ開発体験談

アソビューで新規事業のプロダクト開発を行っている竹内です。

みなさん、モノレポを快適に使ってますか? 以前以下のブログで sparse checkout のことを書きましたが、実はこのブログを書いた時には小さな修正をちょろちょろやるくらいでした。最近 sparse checkout を使った環境で開発したので、実際どうだったかをご紹介したいと思います。

tech.asoview.co.jp

はじめに

sparse checkout と 前回記事のおさらい

上記の以前書いたブログを軽くおさらいすると、

  • モノレポをフルクローンするとなかなか使っていないパッケージも含めて全部 checkout するから必要な分にするといいのでは?
  • sparser checkout 使うと必要な分のみ checkout できてディスクや時間が節約できるよ!

といった感じでした。 また、私の開発環境では IntelliJ を使ってパッケージごとにプロジェクトを開いていますので、その前提で記載します。(だいたい 1 〜 4 プロジェクトほど開いています)

実際に使ってみた

  1. 開発には大きな支障はなかった
  2. sparse chekout を使っても一部例外を除いて問題なく開発できる
  3. 必要になったら必要な分だけパッケージを追加できる
  4. sparse checkout 用の Shell 関数作ったら clone や パッケージ追加がより楽になった

1、 2 については、当たり前といえば当たり前ですが、後述する例外を除けば至って普通に開発できました。また、追加で「このパッケージも修正必要だ!」となった場合も sparse checkout add をすれば OK でした。 3 について、sparse checkout は IntelliJ から行えないようで、ターミナルから実行する必要があります。その都度パラメータを指定することは面倒だったので、Shell 関数を作りました。パラメータを覚えたりディレクトリを打つのも大変なのでとても便利でした。今回は以下 2 つを作成しました。

  1. sparse checkout で clone する関数
  2. sparse checkout で ディレクトリ(パッケージ) を追加する関数

sparse checkout を気軽に行うためのスクリプト例

以下のようなスクリプトを使いました。(エラー処理は割愛, macOS, zsh で確認しています)

1つ目のスクリプトを簡単に説明すると以下の通りです。

  • sparse checkout でクローン
  • 必ず使うディレクトリを sparse checkout add で追加
  • gsco_add(後述) で任意のパッケージを追加
  • 必要があれば初期処理実行
# 1. sparse checkout で clone する関数
gsco_clone() {
  git clone --filter=blob:none --sparse <git repo URL> $1
  cd $1
  git sparse-checkout add dir1 dir2
  gsco_add
  # <必要あればここに初期処理>
  echo "Finished!"
  echo "If you would like to add more packages, please type 'gsco_add' in $(pwd) and select packages you would like to checkout."
}

以下のように使います。こうすると monorepo ディレクトリ配下に sparse checkout で clone します。

$ gsco_clone monorepo

2 つ目のスクリプトを簡単に説明すると以下のとおりです。

  • packages ディレクトリ配下のディレクトリをリポジトリから抽出
  • peco でディレクトリを選択させる(peco は別途インストールが必要です)
  • 選択されたディレクトリを sparse checkout に追加する
# 2. sparse checkout で ディレクトリ(パッケージ) を追加する関数
gsco_add() {
  git ls-tree HEAD --name-only --full-name `git rev-parse --show-toplevel`/packages/|awk -F "/" '{print $1"/"$2}'|uniq|peco|git sparse-checkout add --stdin
}

課題と注意点

  1. checkoutしてないパッケージにコンフリクトが起きるとそのパッケージを checkout せざるを得なくなる
  2. パッケージ横断 の検索ができない

1 について、あまり起きることではないのですが、他のチームの変更等により発生する可能性があります。私は ステージング環境へのリリースブランチ へ master ブランチの内容を手元でマージしようとしたときに発生しました。該当パッケージを checkout してコンフリクト解消しましたが、なかなか大変でした。生存期間が長いブランチでなければ、発生することはかなり減るのではと思います。

2 について、IDE の力でリポジトリ横断で検索したいことがあっても checkout していないのでできないです。これも限られた状況ですが、この場合はフルクローンして、モノレポを1つの IntelliJ プロジェクトでオープンするのがいいかもしれません。

補足

sparse checkout とは直接関係ないですが、 以下のブログで git worktree も紹介されていたので使ってみました。

tech.asoview.co.jp

パッケージによってブランチを変えたい場合に便利でした。特に以下 2 点です。

  • sparse checkout したディレクトリを引き継いでくれる
  • 同一ブランチを異なる workspace で checkout できなくしてくれる

sparse checkout でやるのももちろんいいのですが、必要なパッケージを再度指定しなくていいのは特に便利でした。ただ、worktree とは関係ないですが、IntelliJ のプロジェクト設定は都度必要です。

これからどうする?

今後は以下を試してみようと思っています。

  • sparse checkout は使わずにフルクローンする
  • IntelliJ でパッケージごとにオープンせず、モノレポ全体をオープンする

最近 PC が新しくなってマシンパワーが上がった(M3 24GB)こともあり、もうモノレポとか気にせず1つのプロジェクトでやってしまえばいいのでは?と思っています。どうやら弊社CTOがこのやりかたらしく、触発されたので私も試してみようと思います。

まとめ

  • sparse checkout を使えば必要なディレクトリのみで普通に開発できたよ
  • IDE で sparse checkout の操作ができないのでスクリプトあると便利だよ
  • checkout 外のディレクトリでコンフリクトが起きるとまぁまぁ大変だったよ(あまり起きないけど)
  • 複数のブランチを同時に checkout したい場合は worktree を使うと便利だよ
  • マシンパワーがあればモノレポフルクローン+1プロジェクトでもいいかも??

といったように、sparse checkout で新たに発生しうる事象もあるので、その点も踏まえて小さく始めるのがいいと思います。

PR

アソビューではより良いプロダクトを素早く世の中に届けられるよう、様々な挑戦を続けています。 私達と一緒に働くエンジニアを募集していますので、興味のある方はぜひお気軽にエントリーください!(カジュアル面談もやってます!)

www.asoview.co.jp