atama plus techblog
👻

実務で使うJujutsu:Git経験者のための実践ガイド

に公開

atama plusでエンジニアをしているkiraです。
こちらは atama plus Advent Calendar 2025の22日目の記事です。

https://zenn.dev/atamaplus/articles/8bb88e007fd0c6

はじめに

みなさん、Gitを使っている中で難しいなと感じたことはないでしょうか?

私はrebaseをしたりcherry-pickをしたりするときに難しいと感じることが多く、その度にどうやるんだっけ?と調べてから使っていました。rebaseの途中でコンフリクトが生じて迷子になりgit reset --hardしたこともしばしばありました。

この記事では、後発のバージョン管理ツールとしてGitの経験を踏まえて設計されたJujutsuを実務に取り入れやすい形で紹介します。実務ユースケースメインで紹介しようと思うので、Jujutsuのインストールや設定、一通りの操作方法についてはよくまとまっている先行記事[1][2][3]を参照してください。

https://github.com/jj-vcs/jj

想定読者

  • Gitを一通り習熟している方
    • 特にチームで作業していて複数のブランチを行き来することが多い方
    • 特にrebaseやstashでコンフリクトが生じて困ったことがある方
  • Jujutsuは聞いたことあるけど、触ったことがない方
  • 少し新しいことにチャレンジしてみたい方

この記事に書いていること

  • 実務ユースケースを題材にしたJujutsuの使い方
  • Jujutsuの連携ツールの紹介
  • Jujutsuを使う上での注意点

この記事に書いていないこと

  • Jujutsuの高度な履歴操作(jj split, jj squashなど)
    • これらはJujutsuの大きな強みですが、まずは普段使いに慣れることを優先しています
    • 慣れてきたら、連携ツールとして紹介しているVisualJJを使って履歴操作を試してみることをお勧めします
  • Jujutsuのインストール方法や設定方法

実務ユースケースにおけるGitとJujutsuの操作比較

まずは使えるようにする

Git
git clone https://github.com/{owner}/{repo}
Jujutsu
jj git clone https://github.com/{owner}/{repo}
  • jj git cloneした場合、GitもJujutsuも使えるリポジトリになります。Gitが.gitフォルダで履歴を管理するのに加えて、Jujutsuは.jjフォルダで履歴を管理します。
  • .jjフォルダではGit以上に履歴を管理してます。Gitがコミット履歴を管理しているのに対して、Jujutsuはコミット履歴に加えて操作履歴(operation log)を管理しています。そのため、jj undoにより操作を戻すことや、stashをせずにブランチを移動することができるようになっています。

開発ブランチからFeatureブランチを作成する

Git
git checkout dev
git pull
git checkout -b feature/new-feature
# 作業する
git add .
git commit -m "xxxxxx" # 作業後にしか説明が書けない
# さらに作業する
git add .
git commit -m "yyyyyy"
Jujutsu
jj bookmark track dev@origin
jj new dev@origin
# 作業する
jj describe -m "xxxxxx"
jj new
# さらに作業する
jj describe -m "yyyyyy"
jj new
  • Gitのブランチに相当するものをJujutsuではブックマークと呼んでいます。
  • Gitでは明示的にブランチを切ってから作業を始めることになりますが、Jujutsuではjj newを使って作業を始めていきます。この段階でブランチ名を指定する必要はありません。
  • Jujutsuではgit add相当の操作は不要です。
  • Jujutsuではjj newを繰り返して変更を積んでいきます。変更に対して説明を付与することができるのですが、git commitと異なりいつでも付けることができます。作業前でも作業中でも構いませんし、説明を付けずにjj newをしていった後で戻ってきて説明を付けることもできます。

開発ブランチの更新をFeatureブランチに取り込む

Git
# feature/new-featureで作業中
git checkout dev
git pull
git checkout feature/new-feature
git rebase dev
# コンフリクトが発生したら...
git add .
git rebase --continue
# うまくいかなければ
git rebase --abort
Jujutsu
# feature/new-featureで作業中
jj git fetch # リモートの変更を取得(trackしているdev@originも更新される)
jj rebase -d dev@origin
# コンフリクトが発生したら...
jj resolve --list  # 未解決のコンフリクトを確認
jj resolve path/to/file  # ファイルごとに解決
# または、エディタで直接コンフリクトマーカーを編集して解決することも可能

# もしくは、やり直したければ
jj undo
  • GitとJujutsuではコンフリクトの扱いが大きく異なります。
  • Gitでコンフリクトが生じた場合、マージでもリベースでもコンフリクトを解消するまではその状態から抜けられなくなります。Jujutsuでコンフリクトが生じた場合、コンフリクトマーカー付きで通常の状態に戻ります。
  • Jujutsuでもファイルを編集してコンフリクトを解消しなくてはならないのは一緒ですが、特殊な状態になるわけではないのでコンフリクトを一旦そのままにして作業を進めることや別ブランチに移ることができます。
    • 特殊な状態にならないというのが認知負荷的に楽だと感じています。例えば、Gitでリベースに失敗すると普段使っていない操作を思い出したり調べたりする必要がありますし、コンフリクト中は別の作業をすることができません。

Featureブランチをpushする

Git
# 作業を完了させて
git push origin feature/new-feature
Jujutsu
# 作業を完了させて
jj new
jj bookmark set feature/new-feature -r @-
jj git push --allow-new # 初回のみ
jj git push # 2回目以降
  • Gitのブランチがcommitを積むたびにHEADを移動していくのに対して、Jujutsuのブックマークは明示的に移動させる必要があります(ただし、jj bookmark trackで追跡設定したブックマークは自動的に移動します)。
    • これはブランチとブックマークの思想の違いによるもので、ブランチは枝分かれした変更全体をさしているのに対してブックマークは特定のコミットに対して名前をつけたものになります。
  • そのため、Jujutsuではpushする前に変更の先頭に対してブックマークを作る or 移動する必要があります。
    • 例では、作業を完了させた後にjj newをした上で、その直前の変更に対してブックマークをつけています。
    • jj bookmark setでは指定したブックマークがなければ作成し、既に存在すれば移動します。-rでブックマークをつける対象の変更を指定します。@-は現在の変更の一つ前の変更を表しています。

Featureブランチでの作業中に割り込みで他ブランチの作業をする

Git
# feature/new-featureで作業中
git stash  # 現在の作業を退避
git checkout main
git checkout -b hotfix/urgent-bug
# ... 修正作業 ...
git add .
git commit -m "Fix urgent bug"
# 元の作業に戻る
git checkout feature/new-feature
git stash pop  # 作業を復元(コンフリクトの可能性あり)
Jujutsu
# feature/new-featureで作業中
jj bookmark set feature/new-feature # 現在の変更に対してブックマークをつけておく
jj new main@origin
# ... 修正作業 ...
jj new
jj bookmark set hotfix/urgent-bug -r @-
# 元の作業に戻る
jj edit feature/new-feature
  • Jujutsuでは作業中の変更をstashしなくても別途管理されているので、特に気にせずに別の箇所から修正を始めることができます。ただし、後から戻ってきやすいようにブックマークをつけておくとよいです。
    • ブックマークをつけなくてもjj status等で確認できる変更IDを入力すればその箇所に戻ってこれます
  • 開発作業中に割り込みのhotfix対応やレビュー依頼が発生した場合にGitよりもJujutsuの方が便利だと感じることが多いです。

ツール連携

VisualJJ

https://www.visualjj.com/

Visual Studio CodeやCursorを使っている場合は、VisualJJによりグラフィカルな操作を行えます。
本記事では紹介しなかった履歴操作については、VisualJJを使うと直感的に操作できるのでお勧めです。

直感的で分かりやすいUIになっているのですが、Jujutsuの考え方を一通り把握してからでないと(特にメニューの)操作の意味が分からないと思うので、Jujutsuの入門記事を読んでから使い始めると良いと思います。


VisualJJの右クリックメニュー、Jujutsuの知識がないと何それ?ってなる

aicommit2

https://github.com/tak-bro/aicommit2

生成AIにコミットメッセージを書いてもらうツールで、私が探せる範囲ではJujutsuに対応しているものはこのツールのみでした。
Jujutsuで管理しているリポジトリで使った場合は、aicommit2のコマンドのみで、現状の変更に対する説明を付けて自動的にコミットしてくれるので便利です。

注意:Jujutsuを使う上で気をつけること

jj undoについて

  • Jujutsuで操作している流れの中でGitで操作するとJujutsu側から追えなくなり、jj undoが使えなくなります。

force pushについて

  • Jujutsuでは一度pushした変更はimmutable(不変)となり、git push -f 相当のことはできなくなるため、デフォルトの挙動としてはGit以上に安全です。
  • --ignore-immutableオプションを使ってimmutableなコミットを編集すると、その編集されたコミットとその子孫コミットのpushがgit push -f相当として扱われます。
  • Gitがpush時のオプションによって挙動を切り替えているのに対して、Jujutsuは変更の属性がimmutableかどうかで挙動を切り替えています。そのことを意識していないと不意にforce pushしてしまう可能性があります。

.jjフォルダについて

  • Jujutsuによるバージョン管理を止めたいと思った時には、リポジトリルートの.jjフォルダを消せばGit管理のリポジトリに戻ります。
  • ただし、Jujutsuではcommitしなかった変更も.jjフォルダ内に全て残しているため(そのため、Gitのstash操作を意識しなくてもよくなっています)、.jjフォルダを消すとGitのcommitになっていない変更は全て消えてしまいます。

感想:実際乗り換えた方がいいのか

ここからは私の感想になります。
現状のGitとJujutsuの比較について、私は以下の図のようなイメージで認識しています。


GitとJujutsuの便利さのイメージ

ツールとしての便利さという軸で考えたときに、Gitには歴史があるため解説記事も多く、プラクティスも豊富に見つかります。また、周辺ツールも豊富で、cliツールやエディタ連携(また、それらについての解説記事も!)がたくさんあります。一度Jujutsuを触ると、Gitがより低レイヤーな操作を要求すると感じることがありますが、それを補って余りある周辺サポートが用意されています。
一方で、現状のJujutsuは後発として考え方が洗練されているものの、解説記事もツール連携も少ない状態です。加えて、ググラビリティが低すぎます(しばしば呪術廻戦を調べることになります)

そのため、現状は無理してまで乗り換える必要はないと思うのですが、余裕があるときにJujutsuに乗り換えるのであれば履歴操作やブランチ移動が効率的にできるようになります。また、これまで当然のように受け入れてきたバージョン管理の考え方が変わる体験ができるので、少し新しいチャレンジをしたい方にもお勧めです。

脚注
  1. https://zenn.dev/kimkiyong/articles/1806beccb74a88 ↩︎

  2. https://zenn.dev/tommy109/articles/d63b46f398379c ↩︎

  3. https://zenn.dev/zetamatta/books/c1e309aea68960 ↩︎

atama plus techblog
atama plus techblog

Discussion