わたしは記事をmarkdownで記述しているので、普段はGitを使って履歴管理をしています。複数の記事アイデアをとりあえず書き出そうとするとブランチを色々工夫したりいろいろ考えることが多かったのですが、最近Jujutsuという別のバージョン管理ツールを知りました。これがブログの更新フローにとてもよく合っていてすごく嬉しくなったので、コマンドの備忘録とともに紹介しておきたいと思います。
まあコマンドはここや公式ドキュメントをだいぶ参考にしているので、わかる人はそれらを読めばいいと思います。
Jujutsu(jj)入門:概念・導入・最小運用とチートシート(Gitユーザー向け) - Qiita
https://qiita.com/nico4316/items/6122321eacff245a9805
Jujutsuのいいところ
Jujutsu(以下jj)がGitと大きく違うところ、というと色々あるんだとは思いますが、個人的には「変更履歴の枝分かれとブランチが直接紐付かない」こと、「コミット(jjではChange)の分割・統合・Rebaseがかんたん」ということが挙げられます。
ブログの記事を書こうとすると、関連する話題の記事アイデアが出たり、別の記事の増補もしたくなったり、またバックエンド側や外観の変更もしたくなったり、色々とやりたいことが出てきます(よね?)
そういうときにGitだと、一旦変更をStashして脇において作業したり(そしてそのStashを忘れたり)、記事アイデアのぶんだけブランチを切ったり、最新の変更に追いつくためにRebaseをかけたり、「ただ記事を書きたい」ということに対してやるべきことがちょっと多いと感じていました。あと、コマンドがちょっとわかりにくい……。
Jujutsuだと、あるChangeから一つ進んだChangeを何本でも生やすことができるし、それらにブランチと紐付かせる必要がありません。ブランチが必要な場面が個人的には1つ減りました。

上の画像だと、あるChangeから書きかけ記事のChangeが3つ伸びています。この中で一つ記事を書いたら、それにbookmarkとしてmaster(Gitのブランチに相当)をつけてあげれば、リモートの方にも同期されてNetlify経由でデプロイされます。jjではコミットという概念もないので、Changeという変更を入れる箱をつくってあげれば、あとは記事を書いて保存するだけで変更が追従します。
なんか筆が乗っちゃって複数の記事が1つのChangeにできちゃった!というときも大丈夫。jj splitコマンドでChangeを任意の数に分割できます。何を分割Changeで取り込むのかの選択画面もとてもわかりやすいです。

この辺のコマンドは下の記事がわかりやすいです。

チェンジの分割|君のレポジトリを領域展開 - 次世代バージョン管理システム Jujutsu (jj-vcs/jj)の世界
https://zenn.dev/zetamatta/books/c1e309aea68960/viewer/06_split
そんな感じで、自分が記事を管理するのにとてもストレスがなく使うことができて嬉しい限りです。しばらく使ってみようと思います。
jjコマンド個人的チートシート
自分が記事を書いてpushするまでによく使っているもの、使いそうなものを流れのままにメモしていきます。
jj git init --colocate
jjを使い始めるときのコマンドです。特に、すでにあるGitリポジトリで使いたいときや、jjとGitリポジトリを同時に作成したいときに使用します。
jjだけ使いたいときはjj git init .でいいはず。でもGithub連携とかを考えるとまだこれを使うときではないかもしれない。
jj git clone <URL>
Gitリポジトリをcloneしつつjjも使いたいときに使います。まだ使ったことはない(他人のリポジトリをいじる機会がないですからね)
jj log
jjのchangeツリーを表示します。jj initしたらとりあえずこれをして現状を確認してみるのがいいかも。jjで新たについたchange番号は色々と使います。基本的には最新数件の他に枝分かれがあるところのみが表示されるので、長い履歴を表示するのにjj log -n <NUMBER>で件数指定できることも覚えておくといいかもしれません。
jj edit <CHANGE>
CHANGEのchange番号に移動して編集を始めます。すでにリモートリポジトリにpushされているchangeについてはロックされている(immutable)ので、どうしても変更したいときは--ignore-immutableオプションが必要です。jjはchange番号を省略できて、jj logで表示されたchange番号のうち、色がついているところさえ書いておけばchangeを指定できます。長いchangeログがあってもせいぜい3文字しか入力することはないはず。
jj new <CHANGE>
CHANGEのchange番号から始まるchangeを新しく作成します。
jj new <BOOKMARK>
BOOKMARK (Gitでいうブランチ)から新たにchangeを作成します。jj new mainとかしておけばメインブランチにすぐ生やせるので楽。ちなみにjj newだけだと今編集しているchangeから新たにchangeを作成します。
jj status
git statusに相当します。どこが編集されているのか確認できます。
jj diff
こちらも変更確認用。現在のchangeと直前のchangeでの変更の差分を取ります。指定したchangeとの差分を取りたいときはjj diff -f <CHANGE1> -t <CHANGE2>とすれば2つのchangeの差分を比較できます。こういうときに横並びで表示してほしいですけどそういうプラグインとかあるのかな。
jj desc -m "<DESC>"
changeに説明文をつけます。Gitでいうコミットメッセージに相当します。何回でも書き直せるので便利。
jj bookmark create <BOOKMARK>
新たにBOOKMARKのbookmarkを現在のchangeにつくります。このとき、リモートリポジトリには何も影響しません。リモートリポジトリに紐付けたいときはjj bookmark track <BOOKMARK>を使用します。
jj bookmark set <BOOKMARK> -r <CHANGE>
CHANGEで指定したchangeにBOOKMARKを付与します。jjではchangeを作成してもbookmarkの位置は変わらないので、これで明示的にどこが指定されているかを示してあげます。
jj git push --bookmark <BOOKMARK>
指定のbookmarkをリモートリポジトリにpushします。--bookmark <BOOKMARK>を省略したときは、現在のchangeがpushされる……はず(やったことない)。これをすると、bookmarkがついているchangeの直後に新しいchangeが作成されます。次の変更はここをいじればOK。
jj abandon <CHANGE>
指定のchangeを削除します。Gitから移行したときはなんか謎のchangeとかがあったりする(するよね?)ので、rebaseなどを使って整理しますが、これは最終手段。
jj op undo
直前の操作を取り消します。操作履歴がしっかり残っているほか、Gitよりも柔軟に手戻りができます。
jj split
上にも書きましたが、1つのchangeを分割して複数のchangeを作れます。わたしみたいにあっちこっち色々編集しちゃう人には必須のコマンド。
jj rebase -r <CHANGE1> -d <CHANGE2>
CHANGE1のchangeの親をCHANGE2に変更します。jj splitしたときは、分割したchangeが数珠つなぎになっているので、もし親子関係を変更したいときはこれを使っています(なんか他にもいいコマンドがありそうだけど)。
とりあえずこんなものでしょうか。changeをまとめるjj squashとか、同じファイルに施した複数のchangeをいい感じにまとめてくれるjj absorbとかも便利そうなのですが、現在のところ使う出番がありませんでしたので、ここには入れていません。もうちょっとプログラムファイル向きの機能かなと思います。