モノリポで git worktree が便利そう

エンジニアの村松です。恥ずかしながら最近ようやく PayPay デビューを果たしました。

今回はちょっとした開発 Tips を紹介します。

モノリポ開発で困ること

アソビューが提供しているサービスは多数のアプリケーションで構成されており、これらのアプリケーションはモノリポで管理されています。

開発する内容によっては、影響範囲が複数のアプリケーションに及ぶことがあります。また、これらのアプリケーションをまとめてリリースするのではなく、いくつかに分けてリリースすることもあります。(例えば、バックエンドの API を先にリリースしてからフロントエンドのアプリケーションをリリースしたり…)

アソビューでは、master ブランチへのマージによってアプリケーションがデプロイされます。そのため、リリースを分ける場合にはリリースする単位で feature ブランチを作成する必要があります。

ここで困るのが、『別ブランチで改修した他のアプリケーションをローカルで起動して結合したい』ときにモノリポではどうするのがよいかということです。

以前は、適当な作業用のブランチに必要な改修が含まれるブランチをマージしたり、適当なディレクトリに clone して必要な改修が含まれるブランチを checkout したりしていました。しかし、これだと必要なブランチ (アプリケーション) が増えるほど手間が増えて面倒になります。もう少し効率よく作業できないか調べていたところ、たまたま git worktree の存在を知りました。

「ほー いいじゃないか こういうのでいいんだよ こういうので」(井之頭五郎 / 孤独のグルメ)

git worktree とは

git worktree では1つのリポジトリで複数の作業ツリーを扱うことができます。もともと Git リポジトリは複数の作業ツリーをサポートしており、1つのリポジトリで複数のブランチを作業ツリーとして checkout できます。デフォルトでは、メインの作業ツリーだけが一覧に表示されます。

$ git worktree list
/Users/<USER>/workspace/repo        e562a08b4f7 [feature/service-a]

作業ツリーの追加

新しい作業ツリーは git worktree add で追加します。指定したパスにブランチが checkout されます。例えば、service-b と service-c の改修を含む feature ブランチをそれぞれ checkout する場合は次のようになります。

$ git worktree add ~/worktrees/service-b feature/service-b
$ git worktree add ~/worktrees/service-c feature/service-c

一覧を確認すると作業ツリーが追加されていることが分かります。

$ git worktree list
/Users/<USER>/workspace/repo       e562a08b4f7 [feature/service-a]
/Users/<USER>/worktrees/service-b  f3ce5c04f3c [feature/service-b]
/Users/<USER>/worktrees/service-c  d017566d700 [feature/service-c]

なお、すでに git worktree add している作業ツリーのブランチは、別の作業ツリー上で checkout することはできません。同じブランチをうっかり別のディレクトリ (作業ツリー) で checkout して、作業がコンフリクトするなんていうことが防げそうです。

$ git branch
* feature/service-a
  feature/service-b
  feature/service-c

$ git worktree list
/Users/<USER>/workspace/repo       e562a08b4f7 [feature/service-a]
/Users/<USER>/worktrees/service-b  f3ce5c04f3c [feature/service-b]
/Users/<USER>/worktrees/service-c  d017566d700 [feature/service-c]

$ git checkout feature/service-b
fatal: 'feature/service-b' is already checked out at '/Users/...'

作業ツリーの削除

不要になった作業ツリーは git worktree remove で削除します。git worktree add で作成したディレクトリごと削除されますが、同じリポジトリを参照しているため、その作業ツリー上で commit した内容はメインの作業ツリーに残ります。自分で作成したディレクトリをうっかり消し忘れてローカルにゴミが残り続けるなんていうことがなさそうです。

$ git worktree remove ~/worktrees/service-b
$ git worktree remove ~/worktrees/service-c

モノリポ開発 + git worktree のいいところ

git worktree add で追加した作業ツリーのブランチは、メインの作業ツリーから独立しており、それぞれの作業ツリー上でアプリケーションが起動できます。もちろん、それぞれの作業ツリー上で commit や push をしたり、作業ツリー間でブランチを merge することもできます。

また、git worktree は、ある作業ツリーで作業中に別のブランチを作ってちょっと hotfix を commit したいみたいなときにも便利です。もちろん stash を使ってもいいのですが、複数のブランチで同時に作業できる のが git worktree のいいところかもしれません。

モノリポで複数のアプリケーションを同時に開発するのが以前よりずっとやりやすくなりました。便利ですね!

その他、git worktree の詳細はこちらのドキュメントをどうぞ!

git-scm.com

アソビューでは「ワクワクをすべての人に。」をミッションに、ワクワクを一緒に届けるワクワクメンバーを積極ワクワク採用中です。興味がありましたらお気軽にご応募いただければと思います!

www.wantedly.com