Gitは2005年にLinuxカーネル開発のために生まれました。20年が経ち、開発の前提は大きく変わっています。AIエージェントがファイルを書き換え、並列でブランチを操作し、数分で数十コミットを生成する── こうなると、Gitのステージングエリアやコンフリクト解決の即時強制、脆弱なUndoが摩擦になります。
Jujutsu(jj)は、GoogleがVCS研究として開発し、オープンソースとして公開しているバージョン管理システムです(GitHub: jj-vcs/jj)。Gitリポジトリをそのまま使えるため既存のGitリモートと完全互換でありながら、設計思想を根本から刷新しています。
私たちQurated Labでも、AI駆動開発の現場でjjを試験導入し始めています。この記事では、Gitとの構造的な違い、AIエージェントとの相性、そして具体的な環境構築手順までを整理します。
Gitの「当たり前」を見直す——jjが解決する5つの問題
1. ステージングエリアの廃止
Gitでは git add でファイルを選択し、git commit で確定する2段階の操作が必要です。jjではこの中間地帯が存在しません。ワーキングコピーが常に自動コミットされ、あとから jj split で論理的に分割します。
# Git: 段階的に選択→コミット
git add src/auth.ts
git commit -m "feat: add auth"
# jj: 全変更が自動コミット。必要なら後から分割
jj split # インタラクティブにコミットを分割
「先にコミットして、後から整理する」がjjの哲学です。Gitの「コミット前に選別する」とは逆のアプローチ。AIが連続でコードを書く現場では、この「まず保存、あとで整理」が自然に合います。
2. コンフリクトをコミットできる
Gitではマージやリベースでコンフリクトが発生すると、その場で解決しない限り先に進めません。jjでは、コンフリクトを含んだ状態をそのままコミットできます。解決は後回しにでき、コンフリクトした状態でも他の作業を続行できます。
# Git: コンフリクト発生 → 解決するまでブロック
git rebase main # CONFLICT! 手動で解決必要
# jj: コンフリクトを記録して先に進む
jj rebase -d main # コンフリクトがあってもコミット可能
jj resolve # 好きなタイミングで解決
3. 操作ログと完全Undo
Gitの reflog は各参照(HEADやブランチ)単位の履歴しか持たず、リポジトリ全体の状態を復元するには複数のreflogを突き合わせる必要があります。jjの操作ログ(operation log)は、マージ・リベース・amend・ブランチ移動など全操作をアトミックに記録し、任意の時点にリポジトリ全体を戻せます。
jj op log # 全操作の履歴を表示
jj op restore <id> # 任意の操作時点にリポジトリ全体を巻き戻し
jj undo # 直前の操作を取り消し
4. ブランチレスワークフロー
jjではブランチ名がオプションです。名前のないコミット(anonymous change)でも追跡され、グラフ上で失われません。ブランチは「GitHubへpushする時のラベル」程度の扱いです。
# 新しい変更を作る(ブランチ不要)
jj new # 新しい空のワーキングコピーコミットを作成
# 編集して自動コミット。ブランチ名は後で付けてもいい
jj bookmark create feat-auth -r @- # push時にブランチ名を付与
jj git push
5. 変更IDの安定性
Gitではコミットを amend するとSHA-1が変わり、参照が切れます。jjではchange IDという不変の識別子があり、コミット内容を修正しても同じIDで追跡し続けます。後続のコミットも自動的にリベースされます。
Gitとの比較表
| 観点 | Git | Jujutsu(jj) |
|---|---|---|
| ステージング | git add で選択→ commit | 不要。全変更が自動コミット |
| コンフリクト | 即時解決必須 | コミット可能。後から解決 |
| Undo | reflog + reset(ブランチ単位) | op restore(リポジトリ全体) |
| ブランチ | 必須。checkout -b で作成 | オプション。匿名変更で作業可能 |
| コミット修正 | amend でSHAが変わる | change IDは不変。自動リベース |
| ワーキングコピー | 特殊状態(dirty/clean) | 通常のコミットとして扱う |
| Gitリモート | ネイティブ | 完全互換(同じ .git を使用) |
| 学習コスト | 業界標準、情報豊富 | 概念の再マッピングが必要 |
AI駆動開発での具体的なメリット
ここからが本題です。AIエージェント(Claude Code、Copilot CLI等)と組み合わせた時に、jjのどの特性がどう効くかを整理します。
メリット1:AIの作業が通常操作で消えない
AIエージェントが長時間作業した結果を git reset --hard で吹き飛ばすリスクは現実的です。jjでは全操作が操作ログに記録されるため、通常のVCS操作の範囲であれば jj op restore で復元できます(.jj ディレクトリ自体の削除や破損は別ですが、通常の開発では起きません)。
ユーザーはjjをClaude Codeと数ヶ月使い、「何も壊す心配がないのでAIに任せやすくなった」と報告しています(Anthony Panozzo’s Blog)。
メリット2:並列AIエージェントとの親和性
Claude Codeの /fleet やCopilot CLIの並列サブエージェントは、複数のファイルを同時に書き換えます。Gitでは worktree を使って分離しますが、jjは**jj workspace で複数のワーキングコピーを1リポジトリ内に共存**できます(公式ドキュメント)。
# jj workspace: 1リポジトリに複数の作業空間を作成
jj workspace add ./workspaces/agent-1
jj workspace add ./workspaces/agent-2
# 各AIエージェントが別workspaceで並列作業
Git worktreeと違い、jj workspaceはjjのファーストクラス機能として設計されているため、コンフリクトが起きてもそのままコミットでき、後からマージ時に解決するフローが取れます。
メリット3:Autopilot/Fleet実行の安全なロールバック
AIエージェントのAutopilotモードで「テストが通るまで修正→コミット」を繰り返した結果、おかしな方向に進んでしまうケースがあります。Gitではこの状態からの復帰が複雑ですが、jjでは操作ログから任意の時点に1コマンドで戻れます。
# AIが10回コミットした結果、おかしくなった場合
jj op log # 操作一覧を確認
jj op restore <AI開始前のID> # AI作業前の状態に一発復帰
メリット4:ステージング不要でAIのワークフローが単純化
AIエージェントがGitを操作する際、git add → git commit の2段階は冗長です。特にファイルの追加漏れ(新規ファイルを git add し忘れる)は、AIが起こしやすいミスの一つ。jjでは全変更が自動コミットされるため、このクラスのエラーが原理的に発生しません。
メリット5:コンフリクトでAIが停止しない
Gitでリベース中にコンフリクトが発生すると、AIエージェントは「手動で解決してください」と停止します。jjではコンフリクトをコミットして先に進めるため、AIが止まらない。人間が後から好きなタイミングで解決できます。
デメリットと現実的な制約
正直に書いておきます。jjの導入にはハードルがあります。
| 制約 | 具体的な影響 | 対策・許容範囲 |
|---|---|---|
| IDE連携が未成熟 | VS Code / JetBrainsのGit UI機能はそのまま使えない | ターミナル中心のAI駆動開発なら影響小 |
| チーム全員の習得コスト | 概念の再マッピング(特にブランチレスの考え方) | Git互換なので段階的移行が可能 |
| エコシステムの薄さ | GitHub ActionsやCI/CDはGitコマンド前提 | jjはGitバックエンドなのでCIはGitのまま動く |
| 情報の少なさ | 日本語情報がほぼない。Stack Overflowも少ない | 公式ドキュメントが充実。Discord活発 |
Claude Codeの --worktree 非対応 | Claude Code組み込みのworktree分離機能はjjでは動かない | jj workspace を別途使う必要がある |
jjはGitを「置き換える」ツールではなく、Gitの上に載る「より良いインターフェース」です。リモートやCI/CDは引き続きGitのまま動きます。チーム内で「jjを使う人」と「Gitのまま人」が混在しても問題ありません。
環境構築手順(macOS)
1. インストール
# Homebrewでインストール(最もシンプル)
brew install jj
# バージョン確認
jj --version
2. 初期設定
# ユーザー情報の設定
jj config set --user user.name "あなたの名前"
jj config set --user user.email "your.email@example.com"
# エディタ設定(お好みで)
jj config set --user ui.editor "code --wait"
# シェル補完(zshの場合)
jj util completion zsh > ~/.jj-completion.zsh
echo 'source ~/.jj-completion.zsh' >> ~/.zshrc
source ~/.zshrc
3. 既存Gitリポジトリでの利用開始
# 既存のGitリポジトリに移動
cd your-project
# jjとして初期化(.gitはそのまま維持される)
jj git init --colocate
# 状態確認
jj log # コミットグラフが表示される
--colocate を付けると、.gitディレクトリを共有する形でjjが初期化されます。git コマンドと jj コマンドを同じリポジトリで併用でき、段階的な移行に最適です。
4. 基本ワークフロー(jjらしい使い方)
# ファイルを編集(git addは不要!)
# ... コードを書く ...
# 状態確認(ワーキングコピーが自動コミットされている)
jj status
jj diff
# 変更内容の説明を付ける
jj describe -m "feat: add authentication middleware"
# 新しい変更を始める
jj new
# リモートにpush(ブランチ名を付けてpush)
jj bookmark create feat-auth -r @-
jj git push
5. Claude Codeとの連携
Claude Codeのjj用スキルが公開されています(jujutsu-skill)。導入することで、Claude CodeがGitの代わりにjjコマンドを使って作業するようになります。
# Claude Code用のjjスキルをインストール
cd your-project
mkdir -p .claude/skills
# スキルファイルを配置(詳細は上記リポジトリ参照)
よく使うコマンド早見表
| 操作 | Git | jj |
|---|---|---|
| 状態確認 | git status | jj status |
| 差分確認 | git diff | jj diff |
| コミット | git add . && git commit -m "msg" | jj describe -m "msg" |
| 新しい作業開始 | git checkout -b branch | jj new |
| 履歴確認 | git log --oneline | jj log |
| 直前取消 | git reset HEAD~1 | jj undo |
| リベース | git rebase main | jj rebase -d main |
| push | git push | jj git push |
| コンフリクト解決 | エディタで手動 | jj resolve |
実践ワークフロー——Git × jj × AIエージェントの共存運用
「全部jjに変える」のは現実的ではありません。CI/CDはGit前提、チームメンバー全員がjjを使えるわけではない── そこで、colocateモード(Git/jj共存)をベースに、AIエージェントの作業だけjjで管理するワークフローを設計しています。
全体フロー
sequenceDiagram
participant H as 人間
participant AI as AIエージェント
participant JJ as jj(ローカル)
participant Git as Git(リモート)
H->>JJ: jj new(作業開始)
H->>AI: タスクを指示
rect rgb(230, 255, 230)
Note over AI,JJ: AI作業フェーズ(自動コミット)
activate AI
AI->>JJ: ファイル編集(自動コミット)
AI->>JJ: ファイル編集(自動コミット)
AI->>JJ: ファイル編集(自動コミット)
deactivate AI
end
AI-->>H: 作業完了を報告
rect rgb(230, 245, 255)
Note over H,JJ: 人間の整理フェーズ
H->>JJ: jj log(結果確認)
H->>JJ: jj split(論理単位に分割)
H->>JJ: jj squash(不要コミット統合)
H->>JJ: jj describe(コミットメッセージ整理)
end
rect rgb(255, 245, 230)
Note over H,Git: Gitリモート同期フェーズ
H->>JJ: jj bookmark create feat-xxx
H->>JJ: jj git push
JJ->>Git: push(通常のGit push)
H->>Git: PR作成(GitHub上で通常運用)
end
ポイント解説
AIフェーズ:全て自動コミット
AIエージェントは git add も git commit も不要。jjは jj コマンドが実行されるたびにワーキングコピーのスナップショットを取ります。AIが jj new や jj describe を挟みながら作業すれば、各段階のスナップショットが残ります。整理は後で人間がやればいい。
整理フェーズ:後から構造化
# AIが作った雑多なコミット群を確認
jj log
# 論理的なまとまりに分割
jj split -r <change-id> # 1つのコミットを2つに分割
# 不要な中間コミットを統合
jj squash # 直前のコミットに統合
# メッセージを書き直し
jj describe -m "feat: add auth middleware with tests"
このフェーズがjj最大の価値です。AIが出力した「過程」を、人間が「きれいな履歴」に再構成できる。Gitでは rebase -i でやる作業ですが、jjでは操作ログがあるため失敗しても戻れる安心感が段違いです。
同期フェーズ:チームにはGitとして見える
# PR用にブランチ名を付与
jj bookmark create feat-auth -r <change-id>
# リモートにpush(GitHubにはGitコミットとして届く)
jj git push
他のチームメンバーはjjの存在を知る必要すらない。pushされたものは通常のGitコミットです。PRレビューも通常通り。
AIが暴走した場合の復帰フロー
sequenceDiagram
participant H as 人間
participant AI as AIエージェント
participant JJ as jj
H->>AI: Autopilotで実装を指示
activate AI
AI->>JJ: 修正コミット×5
AI->>JJ: テスト修正×3
AI->>JJ: さらに修正×4(方向性がおかしい)
deactivate AI
H->>JJ: jj op log(操作履歴を確認)
Note over H,JJ: "AI指示前" の操作IDを特定
H->>JJ: jj op restore <指示前のID>
Note over JJ: リポジトリ全体が指示前の状態に復帰
H->>AI: 方針を変えて再指示
Git で同じことをやろうとすると git reflog → git reset --hard → コミットが本当に消えたか確認── と神経を使います。jjなら操作単位で丸ごと巻き戻しなので、「AIに任せて失敗したら戻す」が気軽にできます。
このワークフローの本質は「AIには自由に書かせ、人間が後から整理する」分業です。jjの “先にコミット、後から整理” という設計と、AI駆動開発の “まず実装、後からレビュー” という進め方がそのまま一致しています。
RAPIDワークフローでの活用と所感
Qurated Labでは、AI駆動開発に最適化した独自の開発モデル「RAPID」(Recursive Analysis-Plan-Implement-Deploy)を運用しています。一部開発プロジェクトにjjを導入した結果、RAPIDの各フェーズでjjの特性が具体的に効いていることが見えてきました。
RAPIDの各フェーズとjjの噛み合わせ
| RAPIDフェーズ | jjの効果 | 具体的な使い方 |
|---|---|---|
| A: Analysis(影響分析) | 探索的な調査を気軽に始められる | jj new で分析用のワーキングコピーを作り、AIに自由に探索させる。結論が出たら jj abandon で破棄するか、知見をコミットとして残す |
| P: Plan(計画) | 計画の試行錯誤が安全 | 計画書の作成過程が全て操作ログに残る。方針転換しても jj op restore で戻れるので、AIに複数案を出させやすい |
| I: Implement(TDD実装) | TDDサイクルが単純化 | RED→GREEN→REFACTORの各ステップが自動コミット。AIが書いた過程を後から jj split で「テスト追加」「実装」「リファクタ」に分離できる |
| D: Deploy(リリース) | PR作成が整理しやすい | jj squash でAIの雑多なコミットを論理単位にまとめ、jj bookmark + jj git push でクリーンなPRを作成 |
特に効果を実感している場面
Implementフェーズ(TDD実装)での恩恵が最大
RAPIDのTDD実装では、AIが「テスト作成→最小実装→リファクタリング」のサイクルを高速に回します。Gitでは各ステップをどう commit するか考える必要がありましたが、jjでは何も考えずに全部自動コミット。サイクル完了後に人間が jj log で俯瞰し、jj split と jj squash で「テスト」「実装」「リファクタ」に分離します。
# AIがTDDサイクルを3周した後の整理
jj log # 9つの自動コミットが並ぶ
jj squash --from <red-1> --into <green-1> # RED+GREENを1つに
jj describe -r <change> -m "feat: add auth middleware"
jj describe -r <refactor> -m "refactor: extract validation logic"
この「AIが速度を出し、人間が構造を与える」分業が、jjだと無理なく回ります。
Analysis(影響分析)フェーズでの安心感
影響分析でAIに「この変更の影響範囲を調べて」と指示する際、Gitだとダーティな状態を恐れて慎重になります。jjではjj new で隔離したコンテキストをすぐ作れ、不要なら jj abandon で跡形もなく消せる。探索のコストがゼロになったことで、AIへの指示が大胆になりました。
Planフェーズで複数案を比較
計画段階でAIに「案A: マイクロサービス分割」「案B: モノリス維持」のように複数方針を出させる場合、jjでは各案を別の変更として並列に持てます。どちらかに決まったら、不採用案を jj abandon で捨てるだけ。Gitのブランチ管理のような煩雑さがありません。
正直に感じている課題
- IDE連携の不在はチーム展開のボトルネック。 VS CodeのGit UIが使えないため、ターミナルに慣れていないメンバーには導入しづらい。RAPIDの実装フェーズはClaude Code(ターミナル)中心なので問題ないが、Plan・Reviewフェーズで非エンジニアが関わる場面では使いにくい
jj bookmarkの概念がGitのbranchと異なる。 RAPIDのDeploy(PR作成)フェーズで毎回一瞬戸惑う。慣れの問題だが、チーム全員が同じ速度で慣れるわけではない- 日本語情報がほぼゼロ。 社内で教育ドキュメントを自作する必要があり、その工数はかかった
- colocateモードでGit操作とjj操作を混ぜると、稀にstate不整合が出る。
jj git importで回復できるが、発生すると焦る
現時点での結論
RAPIDワークフローのうちImplement(TDD実装)フェーズに限定すれば、jjは明確に生産性を上げます。Analysis・Planフェーズでも恩恵はありますが、チーム展開の教育コストとの天秤で判断する必要があります。全フェーズへの展開は、IDE連携の成熟を待って判断する方針です。
まとめ——jjは「AIエージェント時代のGitインターフェース」
Jujutsu(jj)は、Gitを置き換えるものではなく、Gitの上により良い操作体験を載せるレイヤーです。特にAI駆動開発においては:
- 全操作のUndoが効く → AIに大胆に任せられる
- ステージング不要 → AIのワークフローが単純化
- コンフリクトで止まらない → 並列AIエージェントが中断しない
- 操作ログで完全追跡 → 何が起きたか常に把握
まずは既存リポジトリで jj git init --colocate を試し、jj log でコミットグラフを眺めてみてください。Gitと併用できるので、リスクゼロで体感できます。バージョン管理まわりの小さなストレスが消える感覚は、一度味わうと戻れなくなります。