新時代のバージョン管理ツールとして最近jujutsuに関心を持ちました。
自分用にjjの概念、導入方法及びチートシートをまとめました。
jjとは
Rust製のバージョン管理ツールで、Google所属のmartinvonz氏が開発しました。ざっくりいうとgitをラップできる、変更履歴を後から編集できる履歴管理ツールです。
メリットとデメリット
jjはコミット履歴を後から編集できるため、レビュー前に変更内容をきれいに整理したいときに重宝します。一方でgitと比べて歴史が浅い分、リファレンスが少なかったり、慣れるまでに多少時間がかかるのは否めないかなと。
メリット
- 既存のgitと同居できる(個人単位から導入可能)
- 履歴を後から整理してコミットできる(レビュー対応で変更内容をまとめ直したいときに便利)
- 後から追記したコミットも整理しやすい
デメリット
- ある程度の学習コストがかかる
- 慣れないうちはgitとjjの管理が二重になりがち
- gitと比べてリファレンスが少ない
jjを使うにあたって押さえたいキーワード/概念
change
変更のまとめ先。gitから見たときの最終的なコミットに相当します。jjでは作業中のchangeが常に存在していて、コミットメッセージをあとから付ける運用になります。
@(working copy)
現在作業中のchangeを指す記号。gitのHEADに近いイメージですが、正確には「今いるchangeのスナップショット」を指します。jj logで@マークが付いているchangeが現在地です。
bookmark
gitでいうブランチ。jjにはブランチという概念がなく、代わりにbookmarkがその役割を担います。gitリポジトリと連携する際はbookmarkがgitブランチに対応します。
operation(op)
jjが行った操作の履歴。jj op logで確認でき、jj op undoで操作単位で巻き戻せます。誤操作のリカバリがしやすいのはこのおかげです。
working copy
現在の作業状態。jjにはステージングエリアがなく、ファイルの変更は自動的に現在のchangeに取り込まれます。git addに相当する操作が不要です。
change ID / commit ID
changeには2種類のIDがあります。change ID(qpvuntsmのような文字列)は変更内容を識別するIDで、amendやrebaseをしても変わりません。commit ID(abc1234のようなハッシュ)はスナップショットを識別するIDで、内容が変わると変わります。「この変更を追いたい」ときはchange IDを使うのが基本です。
インストールと初期設定
# cargo経由
cargo binstall --strategies crate-meta-data jj-cli
# Arch Linux¶の場合
pacman -S jujutsu
# macOS (Homebrew)経由
brew install jj
# バージョン確認
jj --version
既存のgitリポジトリで使い始める場合は、リポジトリのルートで以下を実行するだけです。.gitディレクトリはそのまま残るため、チームメンバーへの影響はありません。
jj git init --colocate
チートシート
基本操作
| やりたいこと | jjコマンド | gitでの相当 |
|---|---|---|
| 状態確認 | jj status |
git status |
| 変更履歴確認 | jj log |
git log |
| 現在のchangeに説明を付ける | jj describe -m "メッセージ" |
git commit -m "メッセージ" |
| 新しいchangeを作る | jj new |
git commitして次の作業へ |
| 差分確認 | jj diff |
git diff |
| 変更を取り消す | jj restore |
git checkout -- . |
履歴の編集
| やりたいこと | jjコマンド | 補足 |
|---|---|---|
| 過去のchangeを修正する | jj edit <change ID> |
そのchangeに移動して編集できる |
| 現在のchangeを親にまとめる | jj squash |
working copyの変更を親changeにまとめる |
| changeを分割する | jj split |
1つのchangeを対話的に2つに分ける |
| changeの順番を入れ替える | jj rebase -r <change> -d <destination> |
|
| 直前の操作を取り消す | jj undo |
jj op undoでも可 |
bookmarkとリモート操作
| やりたいこと | jjコマンド | gitでの相当 |
|---|---|---|
| bookmark作成 | jj bookmark create <name> |
git branch <name> |
| bookmark一覧 | jj bookmark list |
git branch |
| bookmarkを移動 | jj bookmark set <name> -r <change> |
git branch -f <name> <commit> |
| プッシュ | jj git push --bookmark <name> |
git push origin <name> |
| フェッチ | jj git fetch |
git fetch |
よく使うログの見方
# シンプルなグラフ表示
jj log
# 全履歴表示
jj log -r 'all()'
# 特定changeの詳細
jj show <change ID>
おわりに
gitと共存できるので、チームへの影響なく今日から個人の作業フローに取り入れられるのがjjの導入しやすいところだと思います。まずはjj git init --colocateで既存リポジトリに入れてみて、jj logやjj describeあたりから触ってみるのがおすすめです。
参考