最近の[[VCS]]である[[Jujutsu]]を使ってみた。
## 経緯
以下の動画を見てモチベが上がったので勢いで触ってみる。

冷静に考えると、[[Git]]と[[Lazygit]]を使ったほうがいいと思うけど、触らずに評価するのはフェアじゃないし、案外こういうきっかけでツールの乗り換えが発生したりすることはしばしばあるので。
## 環境
| 対象 | バージョン |
| ----------- | ---------- |
| [[macOS]] | 15.7.1 |
| [[Jujutsu]] | 0.34.0 |
| [[mise]] | 2025.9.14 |
## インストール
公式サイトには[[mise]]のインストール方法はない。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://jj-vcs.github.io/jj/latest/images/favicon-96x96.png" />
<span class="link-card-v2-site-name">jj-vcs.github.io</span>
</div>
<div class="link-card-v2-title">
Installation and setup - Jujutsu docs
</div>
<a href="https://jj-vcs.github.io/jj/latest/install-and-setup/"></a>
</div>
...が、インストールできたのでそれで。
```console
mise use -g jujutsu
```
バージョン確認。
```console
$ jj --version
jj 0.34.0-22900c9a9ba362efa442fed2dd4e6e1d5c22cc7a
```
## チュートリアル
公式のチュートリアルをやってみる。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://jj-vcs.github.io/jj/latest/images/favicon-96x96.png" />
<span class="link-card-v2-site-name">jj-vcs.github.io</span>
</div>
<div class="link-card-v2-title">
Tutorial and bird's eye view - Jujutsu docs
</div>
<a href="https://jj-vcs.github.io/jj/latest/tutorial/"></a>
</div>
ただ、そのままじゃ面白くないのでリポジトリは[[🦉Toki]]にする。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://github.githubassets.com/favicons/favicon.svg" />
<span class="link-card-v2-site-name">GitHub</span>
</div>
<div class="link-card-v2-title">
GitHub - tadashi-aikawa/toki: macOSのセットアップ/カスタマイズプロジェクト 誓いの時は来た! 今 わたしは あなた(Windows)を超える!!
</div>
<div class="link-card-v2-content">
macOSのセットアップ/カスタマイズプロジェクト 誓いの時は来た! 今 わたしは あなた(Windows)を超える!! - tadashi-aikawa/toki ...
</div>
<img class="link-card-v2-image" src="https://repository-images.githubusercontent.com/977129105/89cc86a4-ebae-4927-8d0e-a1707375fb45" />
<a href="https://github.com/tadashi-aikawa/toki"></a>
</div>
### クローン
ディレクトリを作成して移動。
```console
mkdir jujutsu-sandbox
cd jujutsu-sandbox
```
`jj git clone` コマンドでクローンすると色々出てくる。
```console
$ jj git clone https://github.com/tadashi-aikawa/toki
Fetching into new repo in "/Users/tadashi-aikawa/tmp/jujutsu-sandbox/toki"
remote: Enumerating objects: 2643, done.
remote: Total 2643 (delta 82), reused 111 (delta 49), pack-reused 2487 (from 2)
bookmark: main@origin [new] tracked
Warning: Name and email not configured. Until configured, your commits will be created with the empty identity, and can't be pushed to remotes.
Hint: To configure, run:
jj config set --user user.name "Some One"
jj config set --user user.email "
[email protected]"
Setting the revset alias `trunk()` to `main@origin`
Working copy (@) now at: ksptsqqt c71682a9 (empty) (no description set)
Parent commit (@-) : xpkxnntk 9ed2ccb4 main | style(neovim): 変更行や変更箇所のdiffを見やすくする
Added 230 files, modified 0 files, removed 0 files
Warning: Name and email not configured. Until configured, your commits will be created with the empty identity, and can't be pushed to remotes.
Hint: To configure, run:
jj config set --user user.name "Some One"
jj config set --user user.email "
[email protected]"
Hint: Running `git clean -xdf` will remove `.jj/`!
```
### ステータスを表示してみる
リポジトリに移動する。
```console
cd toki
```
[[Starship]]は `HEAD (9ed2ccb)` を示しているので、[[Git]]としてはブランチが指定されていない状態ぽい。
```console
$ jj st
The working copy has no changes.
Working copy (@) : ksptsqqt c71682a9 (empty) (no description set)
Parent commit (@-): xpkxnntk 9ed2ccb4 main | style(neovim): 変更行や変更箇所のdiffを見やすくする
```
`ksptsqqt` は[[変更ID (Jujutsu)|変更ID]]で、`c71682a9` は[[コミットID (Jujutsu)|コミットID]]。
[[Git]]のログはこんな感じ。
```
commit c71682a9eba67b296bbe117017b673b38e6774e6
Author: JJ_EMPTY_STRING <JJ_EMPTY_STRING>
Date: Sun Oct 26 20:22:33 2025 +0900
commit d1202b8c72d6593cddd7fb5b7bad156abdd559aa
Author: JJ_EMPTY_STRING <JJ_EMPTY_STRING>
Date: Sun Oct 26 20:22:30 2025 +0900
commit 9ed2ccb4a14b06e80a6edb16d180a6fff6334f54 (HEAD, origin/main, origin/HEAD, main)
Author: tadashi-aikawa <
[email protected]>
Date: Tue Oct 21 23:32:33 2025 +0900
style(neovim): 変更行や変更箇所のdiffを見やすくする
commit 0bcd0441c29bb5f0835afb2d608d5c89f61ab2e0
Author: tadashi-aikawa <
[email protected]>
Date: Tue Oct 21 23:15:36 2025 +0900
feat(neovim): Diffview.nvimで折りたたまずに表示する
```
`c71682a9` は先頭の仮コミット?であり、[[Git]]の `HEAD` は `9ed2ccb4` である。しかも仮コミットは2つあって謎。これが自動履歴保存というやつなのか? と思ったけど `d1202b8c` はどこにも見当たらない...。
### ファイルを変更してみる
リポジトリに変更が生じると、[[変更ID (Jujutsu)|変更ID]]は同一のまま[[コミットID (Jujutsu)|コミットID]]が変更されるとのこと。
まずは現在の[[変更ID (Jujutsu)|変更ID]]と[[コミットID (Jujutsu)|コミットID]]を改めて確認しておく。
```
Working copy (@) : ksptsqqt c71682a9 (empty) (no description set)
```
ちょうど `mnt/zshrc_base.sh` を変更したかったので変更する。
```diff
# <ESC>lでyazi起動
- bindkey '\el' run_yazi
+ bindkey '\ei' run_yazi
```
`git log --all` で確認してもコミットIDにはまだ変化がない。ただ、`jj st` を実行すると先ほどと内容が変わっている。
```console
$ jj st
Working copy changes:
M mnt/zshrc_base.sh
Working copy (@) : ksptsqqt 006727c8 (no description set)
Parent commit (@-): xpkxnntk 9ed2ccb4 main | style(neovim): 変更行や変更箇所のdiffを見やすくする
```
[[変更ID (Jujutsu)|変更ID]]は `ksptsqqt` のままだが、[[コミットID (Jujutsu)|コミットID]]が `006727c8` に変化している。この変化は `jj` コマンド実行を起因に実行されているらしく、`git log --all` 時点で変化がなかったのは `jj st` を実行する前だったから。
[[Git]]で確認するとこのように分岐している。
```
* 006727c JJ_EMPTY_STRING 2025-10-26 20:39
|
|
| * c71682a JJ_EMPTY_STRING 2025-10-26 20:22
|/
|
* (HEAD, origin/main, origin/HEAD, main) 9ed2ccb
[email protected] 2025-10-21 23:32
| style(neovim): 変更行や変更箇所のdiffを見やすくする
|
```
### ファイルを削除してみる
`AGENTS.md` と `CLAUDE.md` を削除して `jj st` を再実行してみた。やはり[[コミットID (Jujutsu)|コミットID]]が変化している。
```console
$ jj st
Working copy changes:
D AGENTS.md
D CLAUDE.md
M mnt/zshrc_base.sh
Working copy (@) : ksptsqqt fc7db3f5 (no description set)
Parent commit (@-): xpkxnntk 9ed2ccb4 main | style(neovim): 変更行や変更箇所のdiffを見やすくする
```
[[Git]]のツリーはこんな感じ。都度 `HEAD` から分岐していく仕様のようだ。
```
* fc7db3f JJ_EMPTY_STRING 2025-10-26 20:39
|
|
| * 006727c JJ_EMPTY_STRING 2025-10-26 20:39
|/
|
| * c71682a JJ_EMPTY_STRING 2025-10-26 20:22
|/
|
* (HEAD, origin/main, origin/HEAD, main) 9ed2ccb
[email protected] 2025-10-21 23:32
| style(neovim): 変更行や変更箇所のdiffを見やすくする
```
### ファイルを追加してみる
以下のファイルを追加してみた。
![[obs-adr.webp|obs-adr]]
`jj` コマンドを実行。
```console
$ jj
Hint: Use `jj -h` for a list of available commands.
Run `jj config set --user ui.default-command log` to disable this message.
Warning: Refused to snapshot some files:
obsidian-tmp.png: 1.7MiB (1801064 bytes); the maximum size allowed is 1.0MiB (1048576 bytes)
Hint: This is to prevent large files from being added by accident. You can fix this by:
- Adding the file to `.gitignore`
- Run `jj config set --repo snapshot.max-new-file-size 1801064`
This will increase the maximum file size allowed for new files, in this repository only.
- Run `jj --config snapshot.max-new-file-size=1801064 st`
This will increase the maximum file size allowed for new files, for this command only.
@ ksptsqqt (no email set) 2025-10-26 20:45:19 fc7db3f5
│ (no description set)
◆ xpkxnntk
[email protected] 2025-10-21 23:32:33 main git_head() 9ed2ccb4
│ style(neovim): 変更行や変更箇所のdiffを見やすくする
~
```
1MBを超えるファイルはデフォルトだと追加対象にはならないらしい。そういえば動画で言ってた気がする。
> obsidian-tmp.png: 1.7MiB (1801064 bytes); the maximum size allowed is 1.0MiB (1048576 bytes)
[[WebP]]版を追加したらwarningは出なくなった。
```console
$ jj
Hint: Use `jj -h` for a list of available commands.
Run `jj config set --user ui.default-command log` to disable this message.
@ ksptsqqt (no email set) 2025-10-26 20:53:40 44db1658
│ (no description set)
◆ xpkxnntk
[email protected] 2025-10-21 23:32:33 main git_head() 9ed2ccb4
│ style(neovim): 変更行や変更箇所のdiffを見やすくする
~
```
この変更点も今までと同様に `HEAD` から分離しているが割愛する。
### 作業は終わり そして始まる
`jj new` コマンドを実行する。
```console
$ jj new
Working copy (@) now at: uxqqqzun b9faf98d (empty) (no description set)
Parent commit (@-) : ksptsqqt 44db1658 (no description set)
Warning: Name and email not configured. Until configured, your commits will be created with the empty identity, and can't be pushed to remotes.
Hint: To configure, run:
jj config set --user user.name "Some One"
jj config set --user user.email "
[email protected]"
```
今まで `Working copy` として表示されていた[[変更ID (Jujutsu)|変更ID]]が `ksptsqqt` から `b9faf98d` に変化した。代わりに `ksptsqqt` は `Parent commit` に昇格した。
```
* b9faf98 JJ_EMPTY_STRING 2025-10-26 20:57
|
|
* (HEAD) 44db165 JJ_EMPTY_STRING 2025-10-26 20:39
|
|
| * fc7db3f JJ_EMPTY_STRING 2025-10-26 20:39
|/
|
| * 006727c JJ_EMPTY_STRING 2025-10-26 20:39
|/
|
| * c71682a JJ_EMPTY_STRING 2025-10-26 20:22
|/
|
* (origin/main, origin/HEAD, main) 9ed2ccb
[email protected] 2025-10-21 23:32
| style(neovim): 変更行や変更箇所のdiffを見やすくする
```
[[変更ID (Jujutsu)|変更ID]] `ksptsqqt` にあたる[[コミットID (Jujutsu)|コミットID]] `44db165` は、[[Git]]上では `HEAD` となっている。そして次なら[[変更ID (Jujutsu)|変更ID]]へと続いていく。
### 以前の変更を修正する
`mnt/zshrc_base.sh` のコメントを変更し忘れたので修正する。
```diff
- # <ESC>lでyazi起動
+ # <ESC>iでyazi起動
bindkey '\ei' run_yazi
```
このままだと、新しい変更として扱われてしまう。
```console
$ jj st
Working copy changes:
M mnt/zshrc_base.sh
Working copy (@) : uxqqqzun 890d589b (no description set)
Parent commit (@-): ksptsqqt 44db1658 (no description set)
```
```
* 890d589 JJ_EMPTY_STRING 2025-10-26 21:07
|
|
| * b9faf98 JJ_EMPTY_STRING 2025-10-26 20:57
|/
|
* (HEAD) 44db165 JJ_EMPTY_STRING 2025-10-26 20:39
|
|
| * fc7db3f JJ_EMPTY_STRING 2025-10-26 20:39
|/
|
| * 006727c JJ_EMPTY_STRING 2025-10-26 20:39
|/
|
| * c71682a JJ_EMPTY_STRING 2025-10-26 20:22
|/
|
* (origin/main, origin/HEAD, main) 9ed2ccb
[email protected] 2025-10-21 23:32
| style(neovim): 変更行や変更箇所のdiffを見やすくする
```
`jj squash` コマンドを実行する。
```console
$ jj squash
Working copy (@) now at: qzqntpvs 6612a767 (empty) (no description set)
Parent commit (@-) : ksptsqqt 6ec58dae (no description set)
Warning: Name and email not configured. Until configured, your commits will be created with the empty identity, and can't be pushed to remotes.
Hint: To configure, run:
jj config set --user user.name "Some One"
jj config set --user user.email "
[email protected]"
```
ポイントは先ほどの変更 (`Parent commit`) の[[コミットID (Jujutsu)|コミットID]]に変化があること。
```diff
- Parent commit (@-): ksptsqqt 44db1658 (no description set)
+ Parent commit (@-): ksptsqqt 6ec58dae (no description set)
```
[[変更ID (Jujutsu)|変更ID]] `ksptsqqt` の差分を `jj diff` で確認したところ、さきほど `jj squash` で追加した変更点が含まれていた。
```console
$ jj diff --git mnt/zshrc_base.sh -r k
diff --git a/mnt/zshrc_base.sh b/mnt/zshrc_base.sh
index e8ca39ea2d..529fa89d07 100644
--- a/mnt/zshrc_base.sh
+++ b/mnt/zshrc_base.sh
@@ -128,5 +128,5 @@
# <ESC>jでNeovim起動
bindkey '\ej' run_vim
-# <ESC>lでyazi起動
-bindkey '\el' run_yazi
+# <ESC>iでyazi起動
+bindkey '\ei' run_yazi
```
> [!hint]
> `jj diff -r k` でOKなのは、`ksptsqqt` が `k` だけで一意に判別可能だから。色が変わっているので何文字打てばいいかが分かる。
>
> ![[2025-10-26-21-15-13.avif]]
[[Git]]のログも不思議なことになっている。
```
* 6612a76 JJ_EMPTY_STRING 2025-10-26 21:08
|
|
* (HEAD) 6ec58da JJ_EMPTY_STRING 2025-10-26 20:39
|
|
| * 890d589 JJ_EMPTY_STRING 2025-10-26 21:07
| |
| |
| | * b9faf98 JJ_EMPTY_STRING 2025-10-26 20:57
| |/
| |
| * 44db165 JJ_EMPTY_STRING 2025-10-26 20:39
|/
|
| * fc7db3f JJ_EMPTY_STRING 2025-10-26 20:39
|/
|
| * 006727c JJ_EMPTY_STRING 2025-10-26 20:39
|/
|
| * c71682a JJ_EMPTY_STRING 2025-10-26 20:22
|/
|
* (origin/main, origin/HEAD, main) 9ed2ccb
[email protected] 2025-10-21 23:32
| style(neovim): 変更行や変更箇所のdiffを見やすくする
```
`44db165` は一度確定した変更前の変更だが、新たに `6ec58da` が作成されたため `44db165` の世界線はパラレルワールドになってしまったようだ。`6ec58da` の誕生に伴い、その先にある `6612a76` も誕生している。[[Git]]の[[リベース (Git)|リベース]]のような概念。
### 以前の変更を編集する
> [!todo]
> ここから続きをやる