ミツカリ技術ブログ

株式会社ミツカリの開発チームのブログです

GitButler × Claude Codeで複数の機能開発を並列実行してみた

こんにちは、ミツカリCTOの塚本こと、つかびー(@tsukaby0) です。

今回の記事ではGitHubの共同創業者が手がけた次世代Gitクライアント「GitButler」を試してみました。

Virtual Branch(仮想ブランチ)でClaude Codeを3つ同時に走らせて並行開発する、というのを実際にやってみたレポートです。よくある手法としてはgit worktreeを活用する方法やDevinなどの全く別の環境で並列させる方法がありますが、気に入らない部分がいくつかあったので、GitButlerを試してみました。

結論

  • GitButlerは複数のブランチで同時に作業できるGitクライアント
  • Claude Codeと連携すると、複数のAIセッションの変更が自動的に各ブランチに振り分けられる、が完璧ではなさそう
  • Mozilla公式のTodoアプリに3つの機能を同時並行で実装してみた感じ、悪くなかったので十分実践で使えそう
  • git worktree方式やDevin方式と異なり、動作確認が容易な点が良い

GitButlerとは?

GitButlerは、Virtual Branch(仮想ブランチ) という概念で従来のGitワークフローを革新するツールです。

従来のGitでは、ブランチ切り替えには git stashgit checkout → 作業 → git checkoutgit stash pop という工程が必要でした。何らかの作業をシーケンシャルにやっている場合は良いですが、メインの開発もやって、急にきた別のバグ修正もやって、さらにふと気づいた箇所のリファクタリングをして・・・というように複数の作業を並列的にやる場合はgit操作が少し煩雑に感じることもあります。

GitButlerでは、1つの作業ディレクトリで複数のブランチを同時に操作でき、このような並列作業の問題を解消してくれます。

今回やること

Mozilla公式のReact Todoアプリ(mdn/todo-react)をベースに、Claude Codeを使って3つの機能を同時に実装します。

セッション(branch) 機能
1 タスクの優先度(高/中/低)
2 ダークモード対応
3 期限切れタスクのハイライト

準備

1. GitButlerのインストール

https://gitbutler.com/

公式サイトを見てまずはGitButlerをインストールします。brewでも入れられます。

Claude Codeをこの後利用しますが、すでに入っているものとします。

2. サンプルのTodoアプリを用意

Mozilla公式のReact Todoアプリを使います。シンプルな構成で、機能追加の題材として最適です。

後続の作業時(push時)に403エラーが発生するため、Forkしておきます。

# Forkしたリポジトリをクローン
git clone https://github.com/tsukaby/todo-react.git
cd todo-react

# 依存関係をインストール
pnpm install

# 動作確認
pnpm dev

このようなアプリが立ち上がります。

3. GitButlerでプロジェクトを開く

  1. GitButlerを起動
  2. 「Add Project」で todo-react ディレクトリを選択
  3. ターゲットブランチとして main を指定

この状態で以下のような画面になります。pnpmを使ったので一部差分が出ていますね。

後の作業の邪魔になるので、とりあえずコミットしてみます。

Commit to new branch を押すと st-branch-1 が自動で作成されます。 package.jsonpnpm-lock.yaml が自動で対象になっています。

ここでコミットメッセージ等を自動生成できるようなので、Settingsなどで諸々AIの設定をしつつ、 Project settings で、AIを有効化します。

Enable branch and commit message generation

これをONにするとボタンが押せるので Generate を押してみます。

自動生成されました。便利ですね。

この状態でCommitし、PRを作成します。今回は個人開発なので、masterに直接mergeでも良いですが、GitButlerの思想的にはmasterへの直接mergeはないようです。PR経由でMergeします。

まずは、PR作成ボタンを押して作成してから、MergeはGitButler上またはWeb上でやります。

Mergeすると現在のブランチの状態はこうなります。

branch1がmasterにmergeされていますね。workspaceはGitButlerが自動生成したメイン(ホームともいえそう?)のブランチで、複数のブランチを作ってもそれらはこのブランチにも加わります。branch1や2を作ったらそれが仮想ブランチで、それらを全部取り込んでいて現在の作業状態を反映したものがworkspaceということのようです。

GitButlerのGUI上で Update workspace ができるので、それを実行すると以下の画面になります。これによってlocalの仮想ブランチは消えます。便利ですね。

単に自動でcommitさせるだけならばClaude Codeなどでもできます。今回の使い方は本質に触れていないので、次に移ります。

実践:3つのClaude Codeセッションを同時実行

ここからが本番です。GitButlerを使うモチベーションは(AIによる)並列作業です。それを実践していきます。

Step 1: 3つのセッションを作成

新たに三つブランチ(branch 2, 3, 4)を作成します。Create branch を押して作成します。

Step 2: 各セッションにタスクを指示

ここからいよいよ並列作業開始です。それぞれのブランチ(セッション)で以下の指示を同時に出してみます。

※私の環境の場合、指示を与えたところ Claude exited with non 0 error code error: unknown option '--settings' というエラーが表示されてしまいました。 色々試行錯誤した結果、 Project settings -> Agent -> Claude Code path の値を claude から /Users/tsukaby/.claude/local/claude に変更したところうまくいきました。

セッション1(優先度機能)

Todo.jsコンポーネントにタスクの優先度(high/medium/low)を設定できる機能を追加して。
- 優先度によって左側にカラーバーを表示(high:赤、medium:黄、low:緑)
- Formにも優先度選択のセレクトボックスを追加
- App.jsのtasksInitialStateに優先度プロパティを追加

セッション2(ダークモード)

アプリ全体にダークモード対応を追加して。
- App.jsにトグルボタンを配置
- CSS変数を使ってテーマを管理(index.cssに追加)
- ユーザーの選択をlocalStorageに保存
- 初期値はシステムのprefers-color-schemeを参照

セッション3(期限切れハイライト)

期限切れのタスクを視覚的にハイライトする機能を追加して。
- Todo.jsに期限(dueDate)表示を追加
- Formに日付入力フィールドを追加
- 期限切れのタスクは背景を薄い赤に
- 期限が今日のタスクは背景を薄い黄色に
- App.jsのtasksInitialStateにdueDateプロパティを追加

おー、並列で動いております。ワクワクしますね。

GitButlerを使わずとも単純にTerminalでClaude Codeを三つ起動すれば良い話ではありますが、その場合は作業が競合するのでgit worktreeを使ったりすると思います。そのような手間が軽減されているのは良さそうです。

Step 3: 並行後

3つのセッションが同時に動き、GitButlerの画面では各Claude Codeが編集したファイルが、自動的に対応するブランチに振り分けられていきます。

workspaceブランチには各ブランチの変更が全て入っているため、この状態で動作確認すれば三つ全ての変更を確認できるはずです。

どうやら実装は上手くいっていそうです。

  • 優先度機能: できている
  • ダークモード: 切り替えられた
  • 期限切れハイライト: できている

Step 4: GitとGitButlerの状態

予想としてはそれぞれ三つのブランチに正しく変更が入った状態を想像しますが、残念ながら100%上手くはいきませんでした。

まずgitですが、branch3と4は自動で名称が変わりました。これは問題ないし、ありがたいですね。

問題はbranch2です。コミットが正しくできていないようです。

これは変更が競合しているから発生したようです。

この状態で無理やりコミットしようとしても競合エラーになります。

そこで、一旦commitを妨げているbranchの変更を Unapply Stack します。そうするとworkspaceにmergeされていない状態になるので、この状態であればcommitはエラーにならず成功します。

Step 5: 各ブランチをコミット&プッシュ

3つのブランチが揃ったので、それぞれPRを出していきます。

まずは全く競合に影響していないダークモード機能のPRを作成して、Mergeします。

次に期限切れハイライト機能のPRを作成して、Mergeします。

最後に優先度機能のブランチを再び Apply workspace で加えてみますが、案の定Conflictします。

これを解消すると以下のような状態になりました。

実は本来は別のブランチに混ぜるべき内容が間違って含まれているなど、割とその辺りの操作が今回適当だったのですが、何はともあれ複数作業を並行できました。

Claude Code Hooksの設定(オプション)

今回はGitButlerのAgents機能を使いましたが、それを使わず、ターミナルから直接Claude Codeを使いたい場合は、Hooksを設定すると便利です。

詳細はこちらをご覧ください。

https://docs.gitbutler.com/features/ai-integration/claude-code-hooks

GitButlerが各セッションを追跡し、変更を適切なブランチに振り分けてくれます。

実際に使ってみた所感

Good

  • ブランチ切り替えのオーバーヘッドがゼロになった
  • Claude Codeとの連携がスムーズ
  • 変更のドラッグ&ドロップが直感的。今回はその辺り割愛しましたが、Workspace上の変更をどのブランチに入れるか、というのをドラッグ&ドロップで簡単に切り替えられます。

Bad

  • 同じファイルを複数ブランチで編集するとコンフリクトになる。そこは自動で解決されないので、人手による工夫が必要
  • 最初はVirtual Branchの概念に慣れが必要

今回触ってみて向いているユースケースとしては、複数の独立した機能を並行開発したいケースかなと思いました。コンフリクトしてしまうと面倒であることは変わらないですね。この点を考慮するといつかはコンフリクト解消が必要とはいえ、git worktreeのような完全に分離された環境の方が良い気もしてきます。

ただ、git worktreeの場合は今度はbranch1と2の変更を同時に動作確認したいような場合は不便です。また、別フォルダに作ったworktreeは初期設定が済んでないから動作確認がしづらいという問題もあります。私としてはworktreeを使う場合はDevinやClaude Code(web)で良いかなと思いました。

GitButlerは競合が発生した場合面倒であるという問題はあるものの、localでの並列開発をやりやすくしてくれる点で可能性がありそうだなと思いました。

まとめ

GitButlerの仮想ブランチという新たな概念・機能によって並行作業が大幅に楽になる可能性を感じました。

今後も複数のAIを同時に走らせ、あらゆる作業をAI化することで、最高の開発体制を整えていきたいと思います。

現在、ミツカリではITエンジニアを募集しています。興味のある方はぜひお気軽にご連絡ください!

herp.careers