
最近、Claude Code を4並列で動かしながら開発していて、ちょっと困ったことがありました。
git worktreeで4つのディレクトリを作って、それぞれでAIに実装を任せる——ここまでは快適なんですが、いざマージしようとすると「CONFLICT」の嵐。1つのworktreeがコンフリクトで止まると、そこから派生させたい作業も全部ブロックされて、結局AIを遊ばせることになってしまう。
「コンフリクトが起きても作業を止めたくないんだけど…」と思って調べていたら、Googleのエンジニアが中心となって開発しているJujutsu (jj)というVCSを見つけました。これがなかなか良くて、vibe codingスタイルにかなりハマったので共有します。
Jujutsu(jj)とは?
jjはGoogleのエンジニアが始めた、Git互換のオープンソースVCSです。Googleの公式製品ではありませんが、現在もGooglerが中心となって開発を続けています。「Git互換」というのがポイントで、既存のGitリポジトリにそのまま導入できます。
で、何がいいかというと:
- コンフリクトが起きても作業が止まらない: これが一番デカい。コンフリクトはコミットに記録されるだけで、他の作業は普通に続けられる
- 操作を全部記録してる:
jj op logで全履歴が見えて、いつでも戻せる。AIの出力が微妙だったときに地味に助かる - 自動コミット: ファイルを保存した時点でもうコミットされてる。
git addとか要らない - Rust製で速い: まあこれはおまけ
インストール
macOSならbrew install jjで一発です。
| |
Gitとの概念の違い
最初ちょっと戸惑ったのが、Gitと微妙に概念が違うところ。慣れると楽なんですが、最初は「え、ブランチないの?」ってなりました。
| 概念 | Git | Jujutsu (jj) |
|---|---|---|
| 作業コピー | ステージング領域(index)で管理 | 常に1つのコミット(@) |
| ブランチ | 必須(detached HEAD は特殊状態) | 不要(匿名で作業可能) |
| コンフリクト | エラーとして扱う(作業ブロック) | コミットに記録(作業継続可能) |
| 履歴の操作 | rebase(リスクあり) | 自動rebase(安全) |
特に「ブランチ不要」は最初違和感ありましたが、vibe codingだと「とりあえず作業始めて、名前は後で決める」ができるので、むしろ便利でした。
jjの基本操作
既存のGitリポジトリでjjを試すのは簡単です。Gitと併用できるので、気に入らなければ元に戻せます。
リポジトリの初期化
| |
jj logの出力例:
| |
@が現在のworking copyコミット。GitのHEADに近いけど、未コミットの変更も含めて常にコミットとして扱われます。
基本的な変更フロー
Gitに慣れてると最初「あれ?」ってなるんですが、git addもgit commitも要りません。
| |
ファイルを保存した瞬間にもうコミットされてるので、git add→git commitの流れがなくなります。正直これだけでもだいぶ快適。
コミットの編集
過去のコミットを編集するのも楽です。Gitだとgit rebase -iで「ミスったらどうしよう」とビクビクしながらやってたんですが、jjは気軽にできます。
| |
しかも子孫のコミットが自動的にrebaseされるので、依存関係を気にしなくていい。
git worktree vs jj workspace
さて、ここからが本題。vibe codingで並列開発するには「複数の作業ディレクトリ」が必要です。
Gitにはgit worktree、jjにはjj workspaceがありますが、一見似てるようで決定的に違う点がいくつかあります。
基本的な仕組みは同じ
ディレクトリ構造は同じ感じ:
repo/ # メインディレクトリ
├── .git/ # Gitデータ(共有)
├── .jj/ # jjデータ(共有)
└── src/
workspace-1/ # 並列作業ディレクトリ1
└── src/
workspace-2/ # 並列作業ディレクトリ2
└── src/
npm installは各ディレクトリで必要になるのは両者同じ。ここは諦めるしかないです。
決定的な3つの違い
で、ここからが重要。実際に使ってみて「あ、これ全然違うわ」と思った3点。
違い①: コンフリクト時の挙動(これが一番デカい)
git worktreeだとこうなります:
| |
worktree-2が止まると、そこから派生させたい作業も止まる。これが辛かった。
一方、jj workspaceだと:
| |
コンフリクトは「記録される」だけで、他の作業はブロックされません。これ、vibe codingだとめちゃくちゃ助かります。
Technical diagram comparing git worktree vs jj workspace conflict handling. Split screen layout. Left side labeled 'git worktree': shows branch A (green check), branch B (red X with 'BLOCKED'), timeline stops. Right side labeled 'jj workspace': shows change A (green check), change B (yellow '(conflict)' recorded), change C continues (green check). Arrows showing git blocks but jj continues. Clean, professional diagram with color-coded status indicators. Minimal flowchart style. All text in the image must be in Japanese.違い②: 状態の共有と可視性
git worktreeだと、各worktreeの未コミット変更は他から見えません:
| |
jjだと自動コミットされるので、全workspaceから見えます:
| |
「あれ、さっきどこで何やってたっけ?」が減ります。
違い③: 依存ブランチの自動rebase
これも地味に便利。feature-A → feature-B → feature-Cみたいな依存関係があるとき。
git worktreeだと、feature-Aを修正したらB、Cを手動でrebaseする必要があります:
| |
jjだと勝手にやってくれます:
| |
AIが生成したコードを後から微調整することが多いので、これは嬉しい。
vibe codingでの実践ワークフロー
実際に自分がClaude Code 4並列でやってるワークフローを紹介します。
Technical architecture diagram of jj workspace parallel development. Top view showing 4 workspace directories (workspace-1 to 4) arranged in a circle, each labeled with tasks: 'auth', 'database', 'UI', 'tests'. In the center: shared '.jj/' repository hub with bidirectional arrows to all workspaces. Each workspace shows status indicators (green progress bars). Clean, symmetric layout. Modern tech diagram style with consistent spacing and alignment. Blue and green color scheme. All text in the image must be in Japanese.セットアップ
最初のセットアップはこんな感じ。npm installを4回やるのはちょっと面倒ですが、最初だけなので我慢。
| |
並列タスクの開始
各workspaceで別々のタスクをAIに投げます。ターミナルを4つ開いて、それぞれでClaude Codeを動かす感じ。
| |
で、AIが作業してる間に別のworkspaceに切り替えてレビューしたり、次のタスクを考えたりします。
コンフリクト発生時の対処
で、実際にコンフリクトが起きたとき。workspace-1とworkspace-2で同じファイルを編集してしまった場合:
| |
「コンフリクト解決は後でまとめてやる」ができるのがポイント。AIを遊ばせずに済みます。
| |
最終的なマージ
全部終わったらまとめてpush。GitHubへのpushは普通にできます。
| |
Operation Logでプロンプト履歴を追跡
これは副産物的に発見した使い方なんですが、「どのプロンプトで何が生成されたか」を追跡するのにoperation logが便利でした。
Technical diagram illustrating jj operation log concept. Horizontal timeline showing sequence of operations from left to right. Each operation shown as a node with ID (op_001, op_002, etc.) and description ('edit file', 'rebase', 'resolve'). Above timeline: current state marked with '@'. Below: ability to restore to any previous operation shown with curved arrow going backwards. Clean, linear flowchart. Purple and blue color scheme. Timestamps on each node. All text in the image must be in Japanese.全操作の記録
| |
プロンプトをコミットメッセージに記録
自分はAIへのプロンプトをそのままコミットメッセージに入れるようにしてます:
| |
後から「このコード、なんでこうなってるんだっけ」と思ったとき、プロンプトを見返せるので便利。
特定操作への復元
「AIの出力が微妙だったから戻したい」というとき、簡単に巻き戻せます:
| |
Gitだとgit reflogで頑張る場面ですが、jjの方が直感的。
bookmarkでブランチを後から命名
これもvibe codingに合ってる機能。「とりあえず作業始めて、名前は後で決める」ができます。
| |
Gitだと最初にgit checkout -b feature-xxxでブランチ名を決めないといけないんですが、AIに実装させてると「結局何ができたか」は最後までわからないことが多い。jjならその問題がなくなります。
jjを使い続けるべきか?
正直なところ、万人におすすめできるかというと微妙です。
jjが向いてる人
- AIエージェントを並列で使う開発スタイル
- コンフリクトが頻発する環境(同じファイルをよく触る)
- 試行錯誤を繰り返す探索的な開発
- 履歴の整形・編集を頻繁に行う
git worktreeのままでいい人
- チーム全員がGitに慣れている(学習コストを避けたい)
- IDEのGit統合を重視する(jjのIDE対応はまだ発展途上)
- コンフリクトがほとんど発生しない
- 1〜2並列で十分
まとめ
git worktreeで4並列開発してたら「コンフリクトで全部止まる」問題にハマって、jjに移行したら解決した、という話でした。
jjが優位な点を改めてまとめると:
- コンフリクトがブロックしない: 記録して作業継続可能
- 状態の可視性: 全workspaceから全changeが見える
- 自動rebase: 依存する変更を修正すると自動的に伝播
学習コストはありますが、vibe codingで「AIを遊ばせたくない」人には試す価値あると思います。Git互換なので、気に入らなければ元に戻せますし。
まずは既存プロジェクトでjj git init --git-repo .を試してみてください。