本文へスキップ

Git ではなく Jujutsu を AI エージェントに使わせる方法

最終更新: 2026 年 8 月

このページでは、Claude Code と Codex CLI に Git ではなく Jujutsu を使わせるための、プロジェクト単位の設定ファイルを掲載しています。

ファイルをプロジェクトの適切な位置に置くと、AI エージェントは Jujutsu のメンタルモデルと基本のワークフローを参照し、日常的なバージョン管理を jj で行うようになります。

なお同じ設定ファイルは、本書のサンプルリポジトリにも置いてあります。

「Jujutsu を使え」と書くだけでは不十分な理由

最近のモデルは、以前と比べて Jujutsu をずいぶん上手に扱えるようになりました。基本的な用途なら、AGENTS.md に「Git ではなく Jujutsu を使うこと」の一行を追加するだけで AI エージェントが履歴管理に jj コマンドを実行してくれることもあります。

ただ、その指示は「Jujutsu をどう使ってほしいか」までは定めていません。現在の change をいつ再利用するのか、差分をどのように確認するのか、余計な working copy のスナップショットをどう防ぐのか、push して PR を出すときに bookmark をどう扱うのか、そのようなところまでは気を回してくれません。AI エージェントは jj コマンドの使い方をいくらか理解しているかもしれませんが、Jujutsu に合ったワークフローを知りません。

skills もこれを完全には解決しません。skills は AI エージェントが「これは関連する」と判断したときだけ、そのタスク向けの知識を読み込むしくみです。一方で「このセッションを通じて Jujutsu をこう使う」は、常時かかっていてほしい振る舞いの制約です。明示的な指針がなければ、長いタスクの途中でエージェントは使い慣れた Git 型のワークフローへ引き戻されてしまうでしょう。

このページの設定は、だから「Jujutsu とは何か」を教えるためのものというより、AI エージェントの振る舞いを Jujutsu のワークフローに適合させるためのものです。どちらのエージェントについても、次の 3 つを組み合わせています。

  • 常時適用される振る舞いの指示
  • Jujutsu のメンタルモデルと頻出のワークフロー
  • バージョン管理コマンドの実行権限

Claude Code の設定

Claude Codeでは、すべてのセッションで読み込まれる rules を中心に運用する方針にしています。

CLAUDE.md には「Git ではなく Jujutsu を使う」といった最優先事項だけを短く記載し、Jujutsu 特有の概念の説明や用途別の操作手順は .claude/rules/jujutsu-rules.md に分離しています。

またエージェントに Git コマンドの使用を禁じ、日常的な Jujutsu コマンドはユーザーの許可なく実行できるようにする settings.json を同梱しています。

.
├─ .claude/
│  ├─ rules/
│  │  └─ jujutsu-rules.md
│  └─ settings.json
└─ CLAUDE.md
CLAUDE.md
## Version Control — 必須手順

このプロジェクトは **Jujutsu (jj)** でバージョン管理している。詳細なルールは `.claude/rules/jujutsu-rules.md` を参照。

**コード編集を開始する前に、必ず以下の手順を実行すること:**

1. `jj log --ignore-working-copy -r @` で現在の change を確認する
2. description が空かつ diff が空(empty)→ `jj describe -m "<description>"` で description を設定して作業開始
3. それ以外(すでに作業中 or 完了済み)→ `jj new -m "<description>"` で新しい change を作成
4. description は Conventional Commits 形式、英語で記述

**禁止事項:** `git` コマンドの直接使用(`jj git` サブコマンドおよび `gh` CLI は許可)
.claude/rules/jujutsu-rules.md
# Jujutsu (jj) Rules for AI Agents

このプロジェクトではバージョン管理に **Jujutsu (jj)** を使用する。AI エージェントは以下のルールを厳守し、**`git` コマンドは原則使用禁止**とする(`jj git` サブコマンドおよび `gh` CLI を除く)。

---

## AI エージェント向け重要注意

### 用語のマッピング

Jujutsu と Git では用語の意味が異なる。AI は以下の用語の使い分けを徹底すること。

| Git 用語                     | Jujutsu 用語                                 |
| ---------------------------- | -------------------------------------------- |
| commit(名詞として)         | change                                       |
| branch                       | bookmark                                     |
| staging                      | (この概念は存在しない)                     |
| unstaged / uncommitted       | (この概念は存在しない)                     |
| HEAD                         | `@`(working copy)                          |
| stash                        | (この概念は存在しない。`jj new` で代替)    |
| `git add`                    | (不要。自動スナップショット)               |
| `git commit --amend`         | (不要。`@` への変更は自動的に反映される)   |

### Jujutsu の Git との根本的な違い

1. **「未保存の変更」は存在しない**: ファイルを保存した瞬間に現在の change に自動的に含まれる。「この変更を含めますか?」という確認は不要である。
2. **change と revision**:
   - **change**: 作業単位。一意で不変の **change ID** を持ち、内容は可変(mutable)。
   - **revision**: change のスナップショット。編集のたびに新しい revision が作られるが、change ID は不変。
3. **自動 rebase**: change の親を変更すると、子孫の change が自動的に rebase される。手動で rebase チェーンを管理する必要はない。
4. **first-class conflict**: conflict が発生しても操作は中断されず、conflict を含む change として記録される。後から解決可能。
5. **operation log**: すべての操作が記録されており、`jj undo` / `jj op restore` で任意の時点に戻れる。失敗を恐れず操作してよい。

### diff 出力のルール

**`jj diff`、`jj show`、`jj log -p` を実行する際は、常に `--git` フラグを付けること。**

このオプション指定により差分出力が自動的に Git 形式になる。

```bash
# 正しい
jj diff --git
jj diff --git -r @-
jj diff --git --from main --to @

# 禁止
jj diff           # --git なしは禁止
jj diff -r @-     # --git なしは禁止
```

Git 形式の diff では、ファイルの追加・削除・リネーム・パーミッション変更も正確に表現され、AI エージェントによる差分の解析精度が大幅に向上する。

### 読み取り専用操作でのスナップショット抑止

jj はコマンド実行のたびに作業コピーのスナップショットを自動作成する。AI が不用意に状態確認を行うと、他のプロセスでの操作によって operation log の競合が起きるリスクがあるため、**ファイルを変更していない状態**での純粋な読み取り操作には `--ignore-working-copy` を付与すること。

```bash
# ✅ 読み取り専用:ファイル変更を伴わない調査時
jj log --ignore-working-copy
jj log --ignore-working-copy -r 'main..@'
jj diff --git --ignore-working-copy -r @-
jj bookmark list --ignore-working-copy

# ❌ 付けてはいけない場面:ファイル変更直後の状態確認
#    (最新のスナップショットを反映させる必要があるため)
jj status          # 変更直後は --ignore-working-copy を付けない
jj diff --git      # 変更直後は --ignore-working-copy を付けない

# ℹ️  スナップショットだけを取りたい場合
jj util snapshot
```

**判断基準**: 直前にファイルの作成・編集・削除を行った場合は `--ignore-working-copy` を付けない。それ以外の「既知の状態を確認するだけ」の場面では付与する。

### ログ出力の使い分け

通常の状態確認では `jj log` のグラフ表示をそのまま使用する。特定の情報を機械的に抽出する必要がある場合は `--no-graph` と `--template`(`-T`)を活用する。

```bash
# 通常の確認(グラフ付き)
jj log --ignore-working-copy

# 特定情報の抽出(機械可読形式)
jj log --ignore-working-copy --no-graph -T 'change_id.short() ++ " " ++ description.first_line() ++ "\n"'
jj log --ignore-working-copy --no-graph -T 'commit_id.short() ++ " " ++ bookmarks ++ "\n"' -r 'bookmarks()'
```

---

## 基本ワークフロー

### 1. 状態・差分確認

```bash
jj status                                  # 作業コピーの状態確認(変更直後はそのまま実行)
jj log --ignore-working-copy               # 履歴をグラフ表示
jj diff --git                              # 現在の作業コピーの差分(変更直後)
jj diff --git --ignore-working-copy -r @-  # 一つ前の change の差分(読み取り専用)
jj evolog --ignore-working-copy            # 現在の change の変遷履歴
jj op log --ignore-working-copy            # 操作履歴の表示
```

### 2. 作業の開始

現在の change (`@`) の状態に応じて操作を変えること。判断手順は以下の通り。

1. `jj log --ignore-working-copy -r @` で現在の change を確認する。
2. description が空かつ diff が空(empty)なら → `jj describe -m "<description>"` のように description を設定して作業開始。
3. それ以外(すでに作業中 or 完了済み)→ `jj new -m "<description>"` で新しい change を作成。
4. description は Conventional Commits 形式に従い、英語で記述すること。

### 3. 変更操作後の conflict 確認

**`jj rebase`、`jj new`、`jj squash` などの変更操作を行った後は、必ず `jj status` で conflict の有無を確認すること。** Jujutsu は conflict が発生しても操作を中断しないため、気づかずに作業を進めてしまうリスクがある。

```bash
# 変更操作の後は必ず実行
jj status

# 出力に以下のような行が含まれていたら conflict が存在する:
#   The change has 2 conflicts:
#     src/main.rs    2-sided conflict
```

conflict を検知した場合は、作業を進める前に解決すること(手順は「conflict 解決」セクションを参照)。

### 4. ブックマーク操作

bookmark は Git の branch と違って、手動で動かす必要がある。

```bash
jj bookmark create <name> -r @          # 新しいブックマークを作成(-r で対象の revision を指定)
jj bookmark move <name> -t @            # 既存のブックマークを現在の change に移動
jj bookmark list --ignore-working-copy  # ブックマーク一覧
jj bookmark delete <name>               # ブックマークを削除
```

### 5. 変更の分割・復元

```bash
# change を複数に分割(スコープが大きすぎる場合の修正に使用)
jj split -r <revision>

# 特定ファイルを別の revision から復元
jj restore --from <revision> <path>

# change を以前の状態に戻す(evolog で確認した過去バージョンを使用)
jj evolog --ignore-working-copy -r <change-id>    # 過去バージョンを確認
jj restore --from <change-id>/1 --to <change-id>  # 1つ前の状態に復元
```

> **補足**: `<change-id>/n` 記法は `xyz/0` が最新版、`xyz/1` が一つ前のバージョンを指す。`jj evolog` で変遷履歴を確認してから使用すること。

### 6. 履歴の修正・取り消し

- **`jj undo`**: 操作を誤った場合は躊躇なく使用して直前の状態に戻ること。
- **`jj op restore <operation-id>`**: 特定の操作時点まで戻す。`jj op log` で操作 ID を確認できる。
- **`jj abandon @`**: 現在の change 自体を破棄する。

### 7. conflict 解決

Jujutsu では conflict が発生しても操作は中断されず、conflict マーカーが挿入された状態で change が記録される。AI は以下の手順で解決すること。

1. `jj status` で conflict しているファイルを確認する。
2. 対象ファイルを開き、conflict マーカーを含む箇所を**直接編集して正しい状態に書き換える**。

Jujutsu の conflict マーカーは Git とは異なる形式を使用する:

```
<<<<<<<
%%%%%%%
-removed line
+added line
+++++++
content from the other side
>>>>>>>
```

- `%%%%%%%` ブロック: diff 形式。ベースからの変更を `-`/`+` で表現する。
- `+++++++` ブロック: スナップショット形式。もう一方の内容をそのまま表示する。

3. ファイルを保存する。`jj` が自動的に解消を検知するため、`git add` に相当する操作は不要。
4. `jj status` で conflict が消えたことを確認する。

### 8. リモートとの同期

```bash
jj git fetch                       # リモートの最新状態を取得
jj git push -b <bookmark-name>    # bookmark をリモートに push
```

---

## revision 指定の記法(revset)

| 記法                  | 意味                                         |
| --------------------- | -------------------------------------------- |
| `@`                   | 現在の change                                |
| `@-`                  | 1つ前の change                               |
| `@--`                 | 2つ前の change                               |
| `<bookmark>`          | bookmark 名で指定                            |
| `<bookmark>@origin`   | リモートの bookmark                          |
| `main..@`             | `main` から現在の変更までの全 change セット  |
| `empty()`             | 内容が空の change                            |
| `<change-id>/n`       | change の n 世代前のバージョン(0 が最新)   |

---

## 便利に使える revset パターン

| パターン                                    | 用途                             |
| ------------------------------------------- | -------------------------------- |
| `trunk()..@`                                | main から現在までのスタック全体  |
| `mine() & mutable() & ~empty()`             | 自分の作業中の change 一覧      |
| `conflict()`                                | コンフリクトを持つ change        |
| `bookmarks() & ~remote_bookmarks()`         | 未 push のブックマーク           |

```bash
# 使用例
jj log --ignore-working-copy -r 'trunk()..@'
jj log --ignore-working-copy -r 'conflict()'
```

---

## PR 作成ワークフロー

### 基本ルール

1. **ターゲットは常に `main`** — 特に指示がない限り、PR のターゲットブランチは `main` とする。確認は不要。
2. **squash は禁止** — 複数の change を 1 つにまとめてはならない。変更履歴の追跡可能性を維持するため、各 change はそのまま保持する。
3. **確認不要な事項** — 以下について毎回ユーザーに確認する必要はない:
   - 「変更を含めますか?」→ 常に含まれている
   - 「main にマージしますか?」→ 特に指示がなければ main
   - 「squash しますか?」→ しない

### PR 作成手順

```bash
# 1. リモートの最新状態を取得
jj git fetch

# 2. 現在の状態を確認
jj log --ignore-working-copy

# 3. bookmark が設定されていることを確認(リモート含む)
jj bookmark list --all --ignore-working-copy

# 4. bookmark が未追跡の場合は追跡を開始する
jj bookmark track <bookmark-name>@origin

# 5. リモートに push(未 push または更新がある場合のみ)
#    jj log や bookmark list --all から判断して、ローカルとリモートの bookmark が
#    指す revision が一致していれば再 push は不要
jj git push -b <bookmark-name>

# 6. GitHub CLI で PR 作成
gh pr create --base main --head <bookmark-name>
```

---

## トラブルシューティング

### 「The working copy is stale」エラー

人間と AI が同じリポジトリで並行作業している場合や、外部ツールがファイルを変更した場合に発生する。このエラーが出た場合は以下を実行して同期する。

```bash
jj workspace update-stale
```

その後、`jj status` で作業コピーの状態が正常であることを確認すること。

### 「Commit XXXX is immutable」エラー

`describe` や `squash` を実行した際にこのエラーが出た場合、操作対象が保護されたリビジョン(`main@origin` とその祖先)に含まれている。`-r` オプションで指定しているリビジョンが正しいか確認し、mutable な change に対して操作をやり直すこと。

---

## 注意事項

1. **自動保存**: jj は作業ディレクトリの変更を自動的に追跡する。明示的な `add` は不要。
2. **イミュータブル履歴**: デフォルトでは `trunk()` とその祖先が不変。ローカルの mutable な change は自由に編集可能。
3. **conflict の扱い**: jj は conflict を含む change も記録可能。後から解決できるが、**変更操作後は必ず `jj status` で確認すること**。
4. **Git 互換**: `.git` ディレクトリと共存可能。`jj git push/fetch` で Git リモートと連携。
5. **change ID の転送**: change ID は Git commit ヘッダー(`change-id`)としてリモートにも転送される。
6. **glob パターン**: revset 等の文字列パターンはデフォルトで glob として解釈される。部分一致には `substring:` プレフィックスを使用する。
7. **git コマンドの使用制限**: `git` コマンドは状態を壊すリスクがあるため原則禁止。`gh` CLI は内部的に `git` を使用するが、これは許可する。読み取り専用の `git` 操作(`git log` 等)も `jj log` で代替すること。
.claude/settings.json
{
  "permissions": {
    "allow": [
      "Bash(jj status:*)",
      "Bash(jj log:*)",
      "Bash(jj diff:*)",
      "Bash(jj show:*)",
      "Bash(jj file list:*)",
      "Bash(jj root:*)",
      "Bash(jj describe:*)",
      "Bash(jj new:*)",
      "Bash(jj edit:*)",
      "Bash(jj restore:*)",
      "Bash(jj squash:*)",
      "Bash(jj rebase:*)",
      "Bash(jj abandon:*)",
      "Bash(jj evolog:*)",
      "Bash(jj op log:*)",
      "Bash(jj operation log:*)",
      "Bash(jj undo:*)",
      "Bash(jj bookmark list:*)",
      "Bash(jj bookmark create:*)",
      "Bash(jj bookmark move:*)",
      "Bash(jj bookmark advance:*)",
      "Bash(jj bookmark set:*)",
      "Bash(jj bookmark rename:*)",
      "Bash(jj git fetch:*)",
      "Bash(jj config get:*)",
      "Bash(jj config list:*)"
    ],
    "deny": [
      "Bash(git:*)",
      "Bash(jj split:*)",
      "Bash(jj resolve:*)",
      "Bash(jj diffedit:*)",
      "Bash(jj arrange:*)"
    ],
    "ask": [
      "Bash(jj bookmark delete:*)",
      "Bash(jj bookmark forget:*)",
      "Bash(jj bookmark track:*)",
      "Bash(jj bookmark untrack:*)",
      "Bash(jj git push:*)"
    ]
  }
}

Claude Code の設定をダウンロード (.zip)

Codex CLI の設定

Codex CLI には Claude Code の rules に相当するしくみがありません。そこで AGENTS.md には必ず守ってほしい事項に絞って記載、Jujutsu の具体的な使い方は skills を参照するように指示しています。

また Codex にも rules という名前の機能はありますが、サンドボックス外でのコマンド実行を管理するためのものです。ここでは Claude Code の settings.json のコマンドパーミッションの内容を翻案した rules ファイルを同梱しています。

.
├─ .agents/
│  └─ skills/
│     └─ jujutsu/
│        └─ SKILL.md
├─ .codex/
│  └─ rules/
│     └─ jujutsu.rules
└─ AGENTS.md
AGENTS.md
## Jujutsu 運用ルール

このリポジトリではバージョン管理に Jujutsu (`jj`) を使う。  
Git ではなく、常に Jujutsu の概念とコマンドで作業すること。
詳細な手順については `.agents/skills/jujutsu/SKILL.md` を参照。

### 最重要ルール

- raw `git` コマンドは**原則使用禁止**
  - 例外: `jj git ...` と `gh` CLI
- `jj split` / `jj resolve` / `jj diffedit` / `jj arrange` は実行禁止(対話的コマンドのため)
- 読み取り専用であっても `git log` などは使わず、`jj log` などで代替する
- `jj diff` / `jj show` / `jj log -p` では常に `--git` を付ける
- `jj rebase` / `jj new` / `jj squash` などの変更操作の直後は、必ず `jj status` を実行して conflict の有無を確認する
- 特に指示がない限り、PR のベースは `main`
- stacked changes を squash してはならない

### 用語の扱い

Git の用語ではなく、Jujutsu の用語で考えること。

- commit(作業単位) → change
- branch → bookmark
- HEAD → `@`(working copy)
- staging / unstaged / uncommitted という概念はない
- `git add` は不要
- `git commit --amend` は不要
- stash の代わりに必要なら `jj new` を使う

### 作業開始の原則

**コード編集を開始する前に、必ず以下の手順を実行すること:**

1. `jj log --ignore-working-copy -r @` で現在の change を確認する
2. description が空かつ diff が空(empty)→  `jj describe -m "<description>"` で description を設定して作業開始
3. それ以外(すでに作業中 or 完了済み)→  `jj new -m "<description>"` で新しい change を作成
4. description は Conventional Commits 形式、英語で記述

### 基本確認コマンド

必要に応じて以下を優先して使うこと。

```bash
jj status
jj log --ignore-working-copy
jj diff --git --ignore-working-copy
jj evolog --ignore-working-copy
jj op log --ignore-working-copy
```

**補足説明**: AI エージェント自身がファイルを変更した後にそれを確認する場合を除き、純粋な読み取り操作には `--ignore-working-copy` を付与することを推奨。

## conflict の原則

Jujutsu では conflict が起きても操作は中断されない。
そのため、変更操作後に `jj status` を確認せず先へ進んではならない。

conflict があれば、ファイルを直接編集して解消し、再度 `jj status` で確認すること。
`git add` に相当する操作は不要。

## リモート・PR の原則

- リモート同期には `jj git fetch` / `jj git push -b <bookmark-name>` を使う
- PR 作成には `gh pr create --base main --head <bookmark-name>` を使う
- bookmark は branch と違い、自動では移動しない。必要に応じて明示的に操作すること

## 補足

このプロジェクトで Jujutsu に関する詳細な操作を行う場合、必ず Skill `jujutsu` を参照すること。  
Jujutsu 固有の判断が必要な場面では、Skill `jujutsu` を確認する前に作業を進めてはならない。

対象例:
- revset
- conflict 解決
- bookmark 操作
- rebase / squash / split / restore / abandon / undo / op restore
- stale / immutable などのエラー対応
- fetch / push / PR 作成
.agents/skills/jujutsu/SKILL.md
---
name: jujutsu
description: この Skill は、このプロジェクトで AI エージェントがバージョン管理システムとして Jujutsu (`jj`) を安全かつ一貫して使うための詳細手順をまとめたもの。 常設ルールは `AGENTS.md` にあり、この Skill には具体的な操作手順と判断基準を記す。
---

# Jujutsu 運用スキル

## この Skill を使う場面

- 現在の作業状態や履歴を確認したい
- 新しい change を始めたい
- rebase / squash / split / restore を行いたい
- conflict を解決したい
- bookmark を作成・移動・削除したい
- revset で対象を指定したい
- PR を作成したい
- stale / immutable などのエラーに対処したい

## 前提

このプロジェクトでは VCS として Jujutsu を使う。

- raw `git` コマンドは原則使用禁止
- 例外は `jj git ...` と `gh` CLI
- 読み取り専用の `git log` なども使わず、`jj` コマンドで代替する

## 用語のマッピング

Git の用語をそのまま持ち込まないこと。

| Git 用語 | Jujutsu での扱い |
| --- | --- |
| commit(作業単位) | change |
| branch | bookmark |
| HEAD | `@`(working copy) |
| staging | その概念はない |
| unstaged / uncommitted | その概念はない |
| stash | 基本的に不要。必要なら `jj new` |
| `git add` | 不要 |
| `git commit --amend` | 不要 |

### 重要な考え方

1. ファイルを保存した時点で変更は現在の change に含まれる
2. change は作業単位であり、revision はそのスナップショット
3. 親を変更すると子孫 change は自動 rebase される
4. conflict は first-class な状態として記録される
5. すべての操作は operation log に残るので、必要なら `jj undo` や `jj op restore` で戻せる

## diff と log の基本方針

### diff

`jj diff` / `jj show` / `jj log -p` では、常に `--git` を付けること。

```bash
jj diff --git
jj diff --git -r @-
jj show --git
jj log -p --git
```

禁止例:

```bash
jj diff
jj diff -r @-
jj show
jj log -p
```

### 読み取り専用操作でのスナップショット抑止

jj はコマンド実行のたびに作業コピーのスナップショットを自動作成する。AI が不用意に状態確認を行うと、他のプロセスでの操作によって operation log の競合が起きるリスクがあるため、**ファイルを変更していない状態**での純粋な読み取り操作には `--ignore-working-copy` を付与すること。

```bash
# ✅ 読み取り専用:ファイル変更を伴わない調査時
jj log --ignore-working-copy
jj log --ignore-working-copy -r 'main..@'
jj diff --git --ignore-working-copy -r @-
jj bookmark list --ignore-working-copy

# ❌ 付けてはいけない場面:ファイル変更直後の状態確認
#    (最新のスナップショットを反映させる必要があるため)
jj status          # 変更直後は --ignore-working-copy を付けない
jj diff --git      # 変更直後は --ignore-working-copy を付けない

# ℹ️ スナップショットだけを取りたい場合
jj util snapshot
```

**判断基準**: 直前にファイルの作成・編集・削除を行った場合は `--ignore-working-copy` を付けない。それ以外の「既知の状態を確認するだけ」の場面では付与する。

### log

通常の確認ではグラフ付きの `jj log` を使う。
機械的に抽出したいときだけ `--no-graph` と `-T` を使う。

```bash
jj log --ignore-working-copy
jj log --ignore-working-copy --no-graph -T 'change_id.short() ++ " " ++ description.first_line() ++ "\n"'
jj log --ignore-working-copy --no-graph -T 'commit_id.short() ++ " " ++ bookmarks ++ "\n"' -r 'bookmarks()'
```

## 基本ワークフロー

### 1. 状態確認

```bash
jj status
jj log --ignore-working-copy
jj diff --git
jj diff --git --ignore-working-copy -r @-
jj evolog --ignore-working-copy
jj op log --ignore-working-copy
```

用途:

- `jj status`: working copy の状態確認
- `jj log --ignore-working-copy`: 履歴とスタック構造の把握
- `jj diff --git`: 現在の差分確認(変更直後)
- `jj diff --git --ignore-working-copy -r @-`: 一つ前の change の差分確認(読み取り専用)
- `jj evolog --ignore-working-copy`: 現在の change の変遷確認
- `jj op log --ignore-working-copy`: 操作履歴の確認

### 2. 作業の開始

現在の `@` の状態を見て、`describe` にするか `new` にするかを決める。

手順:

1. `jj log --ignore-working-copy -r @` で現在の change を確認する
2. description が空で、かつ diff も空なら、その `@` を使って作業開始する
3. その場合は `jj describe -m "<description>"` を使う
4. すでに作業中、または description / diff があるなら `jj new -m "<description>"` を使う
5. description は Conventional Commits 形式に従い、英語で記述する

例:

```bash
jj log --ignore-working-copy -r @
jj describe -m "feat: add search form"
```

または:

```bash
jj new -m "fix: handle empty input"
```

### 3. 変更操作後の conflict 確認

`jj rebase`、`jj new`、`jj squash` などの変更操作の直後は、必ず `jj status` を実行すること。

```bash
jj rebase -s @ -d main
jj status
```

`jj` は conflict が起きても操作を止めない。
そのため、`jj status` を見ずに先へ進むと conflict を抱えたまま作業を続けてしまう危険がある。

conflict の兆候の例:

```text
The change has 2 conflicts:
  src/main.rs    2-sided conflict
```

### 4. bookmark 操作

bookmark は Git の branch と違い、自動では動かない。必要なら明示的に操作する。

```bash
jj bookmark create <name> -r @
jj bookmark move <name> -t @
jj bookmark list --ignore-working-copy
jj bookmark delete <name>
```

用途:

- 新しい bookmark を作る
- 既存 bookmark を現在の change に移す
- 一覧を確認する
- 不要な bookmark を削除する

### 5. change の分割・復元

#### 分割

change が大きくなりすぎたときは分割する。

```bash
jj split -r <revision>
```

#### 復元

別の revision の状態を一部取り戻したいときは `restore` を使う。

```bash
jj restore --from <revision> <path>
```

#### 過去バージョンへの復元

`evolog` を見て、同じ change の過去状態へ戻すこともできる。

```bash
jj evolog --ignore-working-copy -r <change-id>
jj restore --from <change-id>/1 --to <change-id>
```

補足:

- `<change-id>/0` は最新版
- `<change-id>/1` は一つ前の版
- 実行前に `jj evolog` で確認すること

### 6. 履歴の修正・取り消し

```bash
jj undo
jj op restore <operation-id>
jj abandon @
```

用途:

- `jj undo`: 直前の操作を取り消す
- `jj op restore <operation-id>`: 任意の操作時点に戻す
- `jj abandon @`: 現在の change を破棄する

失敗を恐れず操作してよいが、意図が曖昧なときは `jj op log` で確認してから戻す。

## conflict 解決

Jujutsu では conflict が発生しても、その状態のまま change が記録される。
解決は次の手順で行う。

1. `jj status` で conflict 対象ファイルを確認する
2. ファイルを開き、conflict マーカーを含む箇所を直接編集する
3. 正しい内容に整えて保存する
4. `jj status` で conflict が消えたことを確認する

conflict マーカーの形式:

```text
<<<<<<<
%%%%%%%
-removed line
+added line
+++++++
content from the other side
>>>>>>>
```

意味:

- `%%%%%%%` ブロック: ベースからの差分
- `+++++++` ブロック: もう一方の内容そのもの

注意:

- Git のような `git add` は不要
- 保存すれば `jj` が自動的に解消を検知する

## リモートとの同期

```bash
jj git fetch
jj git push -b <bookmark-name>
```

- `jj git fetch`: リモートの最新状態を取得
- `jj git push -b <bookmark-name>`: bookmark を push

## revset チートシート

### 基本記法

| 記法                  | 意味                       |
| ------------------- | ------------------------ |
| `@`                 | 現在の change               |
| `@-`                | 1つ前の change              |
| `@--`               | 2つ前の change              |
| `<bookmark>`        | bookmark 名               |
| `<bookmark>@origin` | リモートの bookmark           |
| `main..@`           | `main` から現在までの change 集合 |
| `empty()`           | 空の change                |
| `<change-id>/n`     | 同じ change の n 世代前の版      |

### 便利なパターン

| パターン                                | 用途                  |
| ----------------------------------- | ------------------- |
| `trunk()..@`                        | main から現在までのスタック全体  |
| `mine() & mutable() & ~empty()`     | 自分の作業中の change 一覧   |
| `conflict()`                        | conflict を含む change |
| `bookmarks() & ~remote_bookmarks()` | 未 push の bookmark   |

例:

```bash
jj log -r 'trunk()..@'
jj log -r 'conflict()'
jj log -r 'mine() & mutable() & ~empty()'
```

## PR 作成ワークフロー

### 基本ルール

- 特に指示がない限り、PR のベースは `main`
- 複数 change を squash してはならない
- 次のことは毎回確認しなくてよい

  * 変更を含めるか → 常に現在の change に含まれている
  * `main` をベースにするか → 明示がなければ `main`
  * squash するか → しない

### 手順

```bash
jj git fetch
jj log --ignore-working-copy
jj bookmark list --all --ignore-working-copy
jj bookmark track <bookmark-name>@origin
jj git push -b <bookmark-name>
gh pr create --base main --head <bookmark-name>
```

補足:

- 先に bookmark の有無を確認する
- 未追跡なら `track` する
- `jj log` や `bookmark list --all` から判断して、ローカルとリモートの bookmark が指す revision が一致していればすでに push 済みなので、再 push は不要

## トラブルシューティング

### 「The working copy is stale」

人間と AI が並行して同じリポジトリを触った場合や、外部ツールがファイルを書き換えた場合に起こる。

対処:

```bash
jj workspace update-stale
jj status
```

### 「Commit XXXX is immutable」

`describe` や `squash` の対象が `main@origin` やその祖先など、immutable な revision に含まれている。

対処:

1. `-r` で指定した対象が正しいか確認する
2. mutable な change を対象にやり直す
3. 必要なら `jj log` で現在位置を確認する

## 最後の注意事項

1. `jj` には staging の概念がない
2. 作業ディレクトリの変更は自動追跡される
3. 変更操作後の `jj status` は必須
4. `.git` と共存できるが、操作は `jj` 経由で行う
5. `git` コマンドは状態を壊すリスクがあるため原則使わない
6. 迷ったら `jj log` / `jj status` / `jj op log` を見てから動く
.codex/rules/jujutsu.rules
# .codex/rules/jujutsu.rules

# --- allow ---
prefix_rule(pattern = ["jj", "status"], decision = "allow")
prefix_rule(pattern = ["jj", "log"], decision = "allow")
prefix_rule(pattern = ["jj", "diff"], decision = "allow")
prefix_rule(pattern = ["jj", "show"], decision = "allow")
prefix_rule(pattern = ["jj", "file", "list"], decision = "allow")
prefix_rule(pattern = ["jj", "root"], decision = "allow")
prefix_rule(pattern = ["jj", "describe"], decision = "allow")
prefix_rule(pattern = ["jj", "new"], decision = "allow")
prefix_rule(pattern = ["jj", "edit"], decision = "allow")
prefix_rule(pattern = ["jj", "restore"], decision = "allow")
prefix_rule(pattern = ["jj", "squash"], decision = "allow")
prefix_rule(pattern = ["jj", "rebase"], decision = "allow")
prefix_rule(pattern = ["jj", "abandon"], decision = "allow")
prefix_rule(pattern = ["jj", "evolog"], decision = "allow")
prefix_rule(pattern = ["jj", "op", "log"], decision = "allow")
prefix_rule(pattern = ["jj", "operation", "log"], decision = "allow")
prefix_rule(pattern = ["jj", "undo"], decision = "allow")
prefix_rule(pattern = ["jj", "bookmark", "list"], decision = "allow")
prefix_rule(pattern = ["jj", "bookmark", "create"], decision = "allow")
prefix_rule(pattern = ["jj", "bookmark", "move"], decision = "allow")
prefix_rule(pattern = ["jj", "bookmark", "advance"], decision = "allow")
prefix_rule(pattern = ["jj", "bookmark", "set"], decision = "allow")
prefix_rule(pattern = ["jj", "bookmark", "rename"], decision = "allow")
prefix_rule(pattern = ["jj", "config", "get"], decision = "allow")
prefix_rule(pattern = ["jj", "config", "list"], decision = "allow")
prefix_rule(
    pattern = ["jj", "git", "fetch"],
    decision = "allow",
    justification = "Jujutsu の fetch は許可"
)

# --- deny / forbidden ---
prefix_rule(
    pattern = ["git"],
    decision = "forbidden",
    justification = "raw git は使わず、jj コマンドを使うこと"
)
prefix_rule(
    pattern = ["jj", "split"],
    decision = "forbidden",
    justification = "jj split は手動で行うこと"
)
prefix_rule(
    pattern = ["jj", "resolve"],
    decision = "forbidden",
    justification = "conflict は手動で行うこと"
)
prefix_rule(
    pattern = ["jj", "diffedit"],
    decision = "forbidden",
    justification = "jj diffedit は手動で行うこと"
)
prefix_rule(
    pattern = ["jj", "arrange"],
    decision = "forbidden",
    justification = "jj arrange は手動で行うこと"
)

# --- ask / prompt ---
prefix_rule(
    pattern = ["jj", "bookmark", "delete"],
    decision = "prompt",
    justification = "bookmark 削除は確認必須"
)
prefix_rule(
    pattern = ["jj", "bookmark", "forget"],
    decision = "prompt",
    justification = "bookmark forget は確認必須"
)
prefix_rule(
    pattern = ["jj", "bookmark", "track"],
    decision = "prompt",
    justification = "remote bookmark の追跡開始は確認必須"
)
prefix_rule(
    pattern = ["jj", "bookmark", "untrack"],
    decision = "prompt",
    justification = "remote bookmark の追跡解除は確認必須"
)
prefix_rule(
    pattern = ["jj", "git", "push"],
    decision = "prompt",
    justification = "リモートへの push は確認が必要",
    match = ["jj git push -b feature-x"],
)

Codex の設定をダウンロード (.zip)

設定ファイルの使い方

セットアップ

  1. ダウンロードした ZIP ファイルを展開します
  2. 展開したフォルダの中身を . で始まる隠しディレクトリも含めて、ディレクトリ構造を保ったままプロジェクトのルートにコピーします
  3. Claude Code または Codex CLI で新しいセッションを開始します

なおプロジェクトに同名のファイルが既にある場合、そのままコピーすると上書きされます。まず既存のファイルをバックアップしたうえで、内容を手作業でマージしてください。

動作要件

  • Jujutsu がインストールされていて、jj コマンドが使えること
  • 対象のプロジェクトが Jujutsu リポジトリとして初期化されていること
  • Claude Code または Codex CLI がインストールされていること

動作確認したバージョン

  • Jujutsu: 0.44.0
  • Claude Code: 2.1.226
  • Codex CLI: 0.147.0

ライセンス

これらの設定ファイルは Apache License 2.0 で提供します。商用利用・改変・再配布のいずれも可能です。

くわしい条件は、各ダウンロードに同梱の LICENSE ファイルをご確認ください。

本書ではさらに行動な内容を扱います

これらの設定ファイルがあれば、Claude Code と Codex に日々のバージョン管理を Jujutsu で行わせるには十分です。『じゅじゅちゅ!』はさらに先へ進み、次のような実践的なワークフローを扱います。

  • エージェントがタスクを完了するたびに、jj fix でフォーマッターやリンターを走らせる
  • push の前にテスト、ビルド、セキュリティチェックなどを実行させる
  • エージェントが生成した大量の変更を整理・統合する
  • 複数のエージェントを並行して走らせ、その変更をうまく統合する