UPSIDER Tech Blog

「git worktree × mise」による開発環境構築

はじめに

こんにちは。カード事業部でバックエンドエンジニアをしているMitomiです。
近年、AIエージェントの普及により、エンジニアの開発効率は飛躍的に向上しています。私自身も Cursor や Claude Code を複数同時に起動し、AIに作業を任せつつ自分は別のタスクを進める、といったワークフローが日常になっています。

たとえば、AIエージェントにこんな指示を出すことがあります。

  • 「この仕様を調べてほしい」
  • 「この機能の大枠を実装してほしい」

しかし、ここには落とし穴がありました。
初めは、実装中のリポジトリでそのまま調査を行わせていましたが、修正途中のコードが混ざった状態で調査が進むため、正確な情報が得られないことがありました。また、環境構築がまだ済んでいない環境でAIに作業を依頼すると、「ビルドが通るところまで」といった明確なゴールを設定できず、期待通りのアウトプットが得られなかったり、出力後の確認作業が膨らんだりする問題がありました。

こうした経験から、調査はローカルの変更が一切入っていないクリーンな環境で行い、実装は環境構築済みの作業環境で進めるという使い分けが重要だと感じるようになりました。さらに実装タスクが増えれば、その数だけ作業環境を並行して用意したくなりますが、環境を新たに増やすたびに構築作業が必要になるのは大きな手間です。

本記事では、この課題を解決するために私が実務で活用している「git worktree × mise」を組み合わせた効率的な開発環境構築方法を紹介します。

開発環境構築に求めた3つの条件と、その解決策

私が今回の環境構築で重視したのは、次の3点です。

  1. 簡単にローカル環境を複製したい
  2. 他のディレクトリへの影響は可能な限り小さくしたい
  3. ツール管理を簡潔に行いたい

これらを実現するために、以下の2つのツールを採用しました。

1. git worktree

git worktree は Git に標準で含まれるサブコマンドです。

git worktree の基本構文は以下です。

git worktree add <ディレクトリパス> <ブランチ名>

このコマンドを実行すると、指定したディレクトリに新しい作業ディレクトリが作られ、指定ブランチがチェックアウトされた状態になります。

worktrees ディレクトリ配下のloginディレクトリに feature/login-page ブランチ用の作業環境を作る場合は次のようになります。

git worktree add worktrees/login feature/login-page

git clone と異なり、.git ディレクトリを親リポジトリと共有するため、ローカル間で直接commitを共有できるのが特徴です。これにより cherry-pickmergerebase がスムーズに行えます。

注意点として、同一ブランチを複数の作業ディレクトリで同時に使用することは原則できません。(--forceオプションを使えば可能ですがあまりおすすめはしません)

2. mise

mise はRust製の環境構築のためのツールで、

といった複数の役割を1つのツールで利用できるものです。

インストール例(bash

# curl経由
curl https://mise.run | sh
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc

# Homebrew経由
brew install mise
echo 'eval "$(mise activate bash)"' >> ~/.bashrc

言語・ツールの利用例(Go言語)

# 利用可能バージョンを確認
mise ls-remote golang

# インストール
mise install golang@1.23.1   # バージョン指定でインストール
mise install golang@latest   # 最新版をインストールすることも可能

# 有効化
mise use golang@1.23.1        # カレントディレクトリのみ有効
mise use --global golang@1.23.1  # グローバルに有効化

VSCodeIntelliJ IDEA向け拡張も用意されています。

環境構成例

私の現在のディレクトリ構成は次の通りです。

core-service
worktrees
├── backend1
├── backend2
├── frontend1
├── frontend2
├── .env
└── mise.toml
  • core-service(例として作業対象のリポジトリ名を core-service としています)
    • mainブランチに固定し、主に仕様調査に利用
    • worktrees の外に置くことで開発対象ディレクトリと明確に分離でき、次の理由から誤ってmain上で作業してしまうリスクを減らせます
      • core-service をmainブランチで固定しているので、worktrees に作成したディレクトリではmainブランチにチェックアウトできない
      • worktrees 直下に置いていないため、worktrees/mise.toml で定義したmiseの設定の適用範囲外となり開発がしにくい
  • worktrees/*
    • 実際の作業ブランチ用ディレクト
    • mise.toml.envworktrees 直下に置き、全ディレクトリに共通設定を適用
    • mise.toml
[env]
_.file = '.env'

※ Node.jsのようにディレクトリ直下に依存をインストールする言語では、基本的に各作業ディレクトリごとに依存関係を解決する必要があります

実際に使って感じたこと

miseの対応範囲が広く、言語やCLIツールの管理がこれ一つで完結するのはとても便利でした。

この構成により開発ミスは減らせましたが、一方でmainブランチでテストコードを少しだけ書き換えて動作確認をしたいケースなどがあったりと、実行環境が整っていないことによる不便さを感じることもありました。

miseの設定が適用されないことによる制約もあったため、ディレクトリ構成は今後見直しても良いかもしれません。

さらに、mise.toml に複製タスクを定義して git worktree add と依存関係の解決を自動化すれば、環境構築の手間をさらに減らせそうだと感じています。

まとめ

git worktree × mise の組み合わせは、私の開発スタイルと非常に合っていて、複数の作業環境を効率よく使い分けられるようになりました。
環境ごとの依存管理や設定適用も簡単にでき、AIエージェントとの並行作業やマルチタスクがやりやすくなったと感じています。

この記事で紹介した方法は筆者個人の開発スタイルの一例ですが、似た課題を持つ方の参考になれば幸いです。 最後まで読んでいただきありがとうございました。