Fragments of verbose memory

冗長な記憶の断片 - Web技術のメモをほぼ毎日更新

Jan 8, 2026 - 日記

jj-desc: Rust製のjjコミットメッセージ自動生成ツールをリリース

jj-desc: Rust製のjjコミットメッセージ自動生成ツールをリリース cover image

Jujutsu(jj) のコミットメッセージをLLMで自動生成するCLIツール「jj-desc 」をリリースしました。

jjはGoogleが開発しているGit互換のバージョン管理ツールで、強力なundo機能とrevset(リビジョンセット)による柔軟なコミット操作が特徴です。生成されるコミットメッセージはConventional Commits 形式に従います。jj-descはこのjjの特性を活かし、複数のコミットメッセージを一括で生成できる点が大きな特徴となっています。

jj-descの主な特徴

複数LLMプロバイダー対応

以下のLLMプロバイダーをサポートしています:

環境変数またはCLIオプションで簡単に切り替えられます:

1
2
3
export LLM_PROVIDER=anthropic
export ANTHROPIC_API_KEY="sk-ant-..."
jj-desc

revsetを活用したbackfill機能

jj-descの最大の強みは、revsetを活用したbackfill(コミットメッセージの後付け一括生成)機能です。

revsetはjj独自のクエリ言語で、コミット(リビジョン)の集合を柔軟に指定できます。Gitにはない強力な機能で、集合演算(&, |, ~)や条件フィルタを組み合わせて処理対象を自由に選択できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 現在のコミット
jj-desc -r @

# 自分のコミット全部を一括処理
jj-desc -r "mine()"

# mainブランチからHEADまでの範囲
jj-desc -r "@..main"

# mutableな(編集可能な)コミットで説明がないもの(デフォルト)
jj-desc -r "::@ & mutable()"

# 説明のないコミット5件を一括処理
jj-desc -r "::@ & mutable()" -n 5

なぜbackfillが重要か?

開発中は「とりあえずコミット」して後でメッセージを整理したいことがよくあります。Gitの場合、git rebase -iでコミットメッセージを書き換えるのは面倒です。aicommitsなどのツールも基本的には「今からコミットする内容」に対してメッセージを生成します。

jj-descは違います。jjの編集可能なコミット履歴とrevsetを組み合わせることで、過去のコミットに対してもまとめてメッセージを生成できます。作業に集中してコミットを重ね、一段落ついたら jj-desc を実行するだけ。これがjj-descの真価です。

以下のデモでは、説明のない複数のコミットに対して jj-desc を実行し、一括でメッセージを生成しています:

jj-desc demo - backfill multiple commits

確認プロンプトなしの即時適用

jj-descは生成したコミットメッセージを確認なしで即座に適用します。これは一見大胆に見えますが、jjの強力なundo機能(jj undojj op log)を前提とした設計です。

Gitツールでは「本当に適用しますか?」と確認するのが一般的ですが、jjエコシステムでは「やってみて、ダメならundo」が自然なワークフローです。すべての操作が履歴に記録され、簡単に元に戻せるため、確認プロンプトは不要な摩擦となります。

もちろん、慎重に確認したい場合は --dry-run(プレビュー)や -i(インタラクティブモード)も用意しています:

1
2
3
4
5
# プレビューのみ(適用しない)
jj-desc --dry-run

# 1件ずつ確認しながら適用
jj-desc -i -r "mine()"

diff最適化とトークン節約

LLMにdiffを送る前に、自動的に以下の最適化を行います:

  • ロックファイル(Cargo.lockpackage-lock.json等)の自動除外
  • バイナリファイルの簡略化(Binary file {path} changed
  • ユーザー指定の除外パターン(--excludeオプション)
  • 50KB超のdiffへの警告表示

これにより、LLM APIのコスト削減とコンテキスト制限の回避を両立しています。

1
2
3
4
5
# 特定のファイルを除外
jj-desc --exclude "*.json" --exclude "*.yaml"

# 短縮形
jj-desc -x "docs/*" -x "*.lock"

マージコミットの自動判定

jjでは多くのマージコミットが「空」として扱われます(jj FAQ 参照)。jj-descはマージコミットを自動検出し、LLM API呼び出しなしで適切な説明(“Merge commit”)を設定します。

インストール

Homebrew(推奨)

1
brew install tumf/tap/jj-desc

プリビルドバイナリ

各プラットフォーム向けのバイナリをリリースページ から入手できます:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# macOS(Apple Silicon)
curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-installer.sh | sh

# Linux(x86_64)
curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-installer.sh | sh

# Windows(PowerShell)
powershell -ExecutionPolicy Bypass -c \
  "irm https://github.com/tumf/jj-desc/releases/latest/download/jj-desc-installer.ps1 | iex"

Cargoからビルド

1
cargo install --git https://github.com/tumf/jj-desc

基本的な使い方

LLMプロバイダーの設定

まず、使用するLLMプロバイダーのAPI keyを設定します:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# OpenRouter(デフォルト)
export OPENROUTER_API_KEY="your-api-key"

# または OpenAI
export LLM_PROVIDER=openai
export OPENAI_API_KEY="sk-..."

# または Anthropic
export LLM_PROVIDER=anthropic
export ANTHROPIC_API_KEY="sk-ant-..."

# Ollama(ローカルLLM)
export LLM_PROVIDER=openai
export OPENAI_API_KEY="dummy"
export OPENAI_BASE_URL="http://localhost:11434/v1"
export LLM_MODEL="llama2"

コミットメッセージ生成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# デフォルト: 説明のないmutableなコミット全てを処理
jj-desc

# 現在のコミットのみ
jj-desc -r @

# 自分のコミット全部
jj-desc -r "mine()"

# プレビュー
jj-desc --dry-run

# インタラクティブモード
jj-desc -i

aicommit2との違い

jj向けのAIコミットメッセージ生成ツールとしては、aicommit2 が先行して存在します。aicommit2はTypeScript製の汎用ツールで、Git、YADM、jjの3つをサポートしています。

両者の最大の違いはbackfill機能の有無です:

機能jj-descaicommit2
backfill(過去コミットの一括処理)✅ revsetで自由に指定❌ 現在のコミットのみ
対応VCSjj専用Git, YADM, jj
実装言語RustTypeScript
確認プロンプトなし(undo前提)あり
diff最適化✅ 自動フィルタリング-

aicommit2は「今からコミットする」ワークフロー向け。jj-descは「まとめてコミットして後からメッセージを整理する」ワークフロー向けです。

jjの特性を最大限活かしたいならjj-desc、既存のGitワークフローと併用したいならaicommit2をお勧めします。

まとめ

jj-descは、jjのrevsetを活用したbackfill機能が最大の特徴です。作業に集中してコミットを重ね、後からまとめてメッセージを生成する——このワークフローはjjならではのものであり、Git向けツールでは実現できません。

jjユーザーの方はぜひ試してみてください。フィードバックや機能提案はGitHubリポジトリ でお待ちしています。

参考リンク