Jujutsu
jj
git と 100% 互換のバージョン管理システム
https://github.com/jj-vcs/jj/raw/main/docs/images/jj-logo.svg
Jujutsu docs
大事な概念
jj コマンドは作業コピーではなくデータ構造(リポジトリに保存された)に対して動作する
良い記事
【翻訳】 jj init (バージョン管理システム Jujutsu の紹介)
Steve's Jujutsu Tutorial
公式 Docs より読みやすい
セットアップ
code:sh
jj config set --user user.name "sorutrt"
jj config set --user user.email "a@example.com"
https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F100666%2Fc9696d1b-dbc7-42b4-b4c0-eb8ba6212633.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=ef523bc20c39f6af0c7ae969f9c2ce27
https://qiita.com/gony/items/81bc7aed19131322f69d
リビジョンは変更の単位
jj は git の機能を多用している―それで十分な効果が得られるならば。
.gitignore
jj init ではなく jj git init
jj git というコマンド
100% 互換の強み
commit と changeID
https://steveklabnik.github.io/jujutsu-tutorial/hello-world/viewing-the-current-status.html
code:jj st
Working copy (@) : syrkmmwp cf40849d STTモデルを kotoba-wisper v2.0 fast に変更
Parent commit (@-): vwnvqrvy 6cf0f80e (empty) STTを早くする
changeID
最初の syrkmmwp や vwnvqrvy
commit
git の commit と一緒
code:git log
PS C:\Users\user\projects\Anxiety> git log
commit 6cf0f80e1e02c1aa1e7f620b2e02316904b5b37a (HEAD)
...
6cf0f80e が一緒
changeID: zzzzzzz , commit 0000000 のものは empty。root commit という
jj はこの上に変更を作成、Working Copy を追跡
squash workflow
https://steveklabnik.github.io/jujutsu-tutorial/real-world-workflows/the-squash-workflow.html
root()にいるとして
code:新機能作成
jj new
jj desc -m "feature hoge"
で、
$ jj new
(ワーキングディレクトリの内容変更する)
$ jj squash
この方法は git の index を使うのに似てる
実際には git add -a --amend をしている
特定のファイルの変更だけを適用するなら jj squash src/main.rs
jj squash -i でファイルの特定の行の変更だけを適用
jj abandon でワーキングディレクトリの内容削除(git restore . に相当?)
anonmous branch (匿名ブランチ)
https://steveklabnik.github.io/jujutsu-tutorial/branching-merging-and-conflicts/anonymous-branches.html
ブランチは本当に必要か?
git はブランチ中心の設計
git ではブランチはすべてコミットへのポインタ
ポインタには名前が必要だから仕方なくつける
そもそもブランチに名前いる?コミットメッセージだけあればいいでしょ。という発想
jj では(基本的に)ブランチに名前をつけない。parent commit の description が変更内容を示してくれる
ブランチに名前をつけることが有益な場合もある
jj new <changeID> でそこからの変更を作成。これ自体が分岐になる
code:ぜんぶ表示.sh
jj log -r 'heads(all())'
revset
https://steveklabnik.github.io/jujutsu-tutorial/branching-merging-and-conflicts/revsets.html
revision の set(集合)
リビジョン( git でいうコミット的なやつ)の集合を抽出する関数型言語の式
jj のほぼ全てのコマンドは -r / --revision フラグを受け付ける
jj new = jj new -r @(現在の working copy を親リビジョンにして新規変更を作成)
Symbols
@ や change ID, commit ID
Operators
@- はworking copy の親(- が親を指す)
Functions
シンプル(引数がないという意味?)
root(): root change
all(): 全ての可視な変更
mine(): 現在のユーザーが変更した全ての変更
複雑なもの(引数をとるという意味?)
parents(x): x の親の変更
ancestors(x): ::x と同様
ancestors(x, depth): 結果を特定の深さまで制限
ブランチの merge
https://steveklabnik.github.io/jujutsu-tutorial/branching-merging-and-conflicts/merging.html
merge とは?
複数の親を持つ新しい変更
新しい変更は jj new で作るんだったね
$ jj new pzoqtwuv yykpmnuq -m "merge better documentation"
もちろん、jj new [OPTIONS] [REVSETS] なので 3 つの変更を同時に merge できる
ブランチの rebase
$ jj rebase -r xrslwzvq -o pzoqtwuv
working dir の移動
$ jj edit <changeID>
jj の競合 conflict
bookmark について
$ jj bookmark create は名前付きブランチを作成する
jj new の動作と違うのはブランチ名がつくだけ
@ が main ブランチの状態で jj new したあとの @ は main ではない
$ jj bookmark set main
で @ を main にする
ブランチ名はリモートサーバーと同じ変更点にいる必要がある
「ローカルを更新したからリモートも更新」ではなく、「リモートを更新しなきゃいけないからローカルを更新する」
jj と GitHub