ハクソク

世界を動かす技術を、日本語で。

「呪術」メガ合併の楽しさと利益

概要

  • Jujutsuの中上級ユーザーやGitユーザー向けの内容
  • megamergeワークフローの概要と利点を解説
  • octopus merge(複数親マージ)の活用法
  • 作業効率化・コンフリクト削減・ブランチ管理の簡便化
  • 便利なコマンドやエイリアスの紹介と設定例

Jujutsu「megamerge」ワークフローとは

  • megamergeは、複数の作業ブランチを一つのoctopus merge commit(複数親マージコミット)でまとめる手法
  • 各種バグ修正、機能追加、他人のブランチ、ローカル環境用変更など、全ての作業ブランチを一つのmegamergeに集約
  • megamerge自身はpushしない。構成する各ブランチのみをpush対象とする運用
  • 作業コピーが正常動作すれば、全変更の相互作用も保証される安心感
  • Jujutsuではコンフリクトが一級市民のため、マージ時の衝突も最小限に抑えられる

megamergeワークフローの主な利点

  • 全作業の合算状態で常に開発できるため、切り替え作業の負担が激減
  • 小さなPRの作成やドライブバイ修正が容易
  • ブランチの最新化も、megamergeごとまとめて単一リベースで対応可能
  • 複数作業の同時進行が自然に可能となる運用設計

megamergeの作り方と使い方

  • 新規megamerge作成は、含めたい各ブランチを親にして空コミットを作成
    • 例: jj new x y zjj commit --message "megamerge"
  • megamerge上でWIP(作業中)コミットを積み上げる。必要に応じて分割や新規ブランチ化も柔軟
  • 既存コミットへの変更吸収squash --toabsorbコマンドで自動化
    • jj squash --to x --from y --interactive
    • jj absorb --from x
  • 新規コミットの追加別ブランチへの移動rebasebookmark moveで調整
    • jj rebase --revision x --after y --before megamerge
    • jj bookmark move --from y --to x

エイリアス設定例と運用Tips

  • エイリアスで複雑な操作を簡略化
    • [revset-aliases]
      • closest_merge(to):指定コミット近傍の最新マージコミット取得
    • [aliases]
      • stack:任意のリビジョンセットをmegamerge下に再配置
      • stage:megamerge以降の全変更を一括で再配置
      • restack:trunk()に自分の変更のみリベース
  • エイリアス例
    • jj stack x::y:複数の変更をmegamergeに取り込む
    • jj stage:megamerge以降の全スタックを一括で取り込む
    • jj restack:自分が管理するコミットのみtrunk()へリベース

他開発者との協調・メンテナンス

  • 他人のブランチや未管理ブックマークは自動リベース対象外
  • restackエイリアスで自分が管理可能なコミットのみを安全にリベース
  • 複数人・巨大megamergeにも対応可能な運用

TL;DR & 便利コマンドまとめ

  • megamerge複数作業の同時進行マージ地獄回避に最適
  • エイリアス設定で効率的な運用が可能
  • absorbsquash --interactiveで既存コミットへの変更集約
  • rebasestack/stageで新規コミットや複数変更の管理が簡単
  • megamergeはpush対象ではなく、ローカル作業の効率化ツール

主なコマンド例

  • 既存コミットへの変更吸収
    • jj absorb
    • jj squash --to x --interactive
  • 新規コミットの追加
    • jj rebase --revision y --after x
  • megamergeへの一括追加
    • jj stage
  • 特定リビジョンセットの追加
    • jj stack w::z
  • trunk()へのリベース
    • jj restack

megamergeワークフローは、複雑な開発環境や多数の並行作業が発生する現場で、Jujutsuの真価を発揮する強力な手法。効率的なブランチ管理衝突回避を両立したい方におすすめ。

Hackerたちの意見

最近、jjの投稿が増えてるのを見ると嬉しいな。いいツールだよね。これがきっかけで、何人かの友達にgitの固執をやめさせて、新しいことに挑戦させることができたんだ。
この記事には素晴らしいトリックがたくさんあるね。絶対にMegamergeのスキルが上がるよ。ありがとう!ただ、これ(や他のjjのワークフロー)はjjuiを使えばもっと楽になるってことも言っておきたいな。これが一番のTUIだと思うし、この記事の一部を組み込むことを提案したよ。https://github.com/idursun/jjui/discussions/644
最近jjに挑戦してるけど、コードを書くときにVS Codeのgitガターに頼りすぎてるんだ。VS Codeにはjjの同等機能がないみたいで。おすすめのツールがあったら教えて!
visualjj、最高だね!
jjkかjjviewについてだけど、jjkのフルチェンジをレビューするPRを出してるよ。それと、別のユーザーのPRでは、任意の範囲でのdiffができるようになってる(つまり、PRを構成するコミットが個別ではなく、全体として良いかどうかを確認するためのもの)。
僕はVS Codeのgit統合を使って、jjと一緒にあるgitリポジトリを使ってるよ。HEADは@-で、@の変更は作業コピーの変更と見なされるんだ。これでVS Code統合でやってたことは全部できてるよ。
VSC用のjjプラグインはいくつかあるよ。VisualJJとJujutsu Kaizenが多分一番人気かな。 https://www.visualjj.com/ https://github.com/keanemind/jjk
いい記事だね!`jj parallelize` [1] をよく使ってるし、ここでも書いたよ [2]。メガマージのためにコミットのシーケンスをファンアウトするのに役立ってるけど、君のスタックエイリアスは、作業の最後ではなく、リアルタイムで作成するのにすごく便利そうだね。アドバイスありがとう! [1] https://docs.jj-vcs.dev/latest/cli-reference/#jj-parallelize [2] https://blog.chay.dev/parallelized-commits
ちょっと脱線するけど、gitの知識を前提としないjjの良いリソースを知ってる人いる?スティーブのや他の人のは質が高いけど、しばしばgitの同等物で説明されてたり、個人プロジェクトに必要な最低限のgitの基本しか知らない僕には、目的を完全に理解するのが難しいワークフローが多いんだ。もしそういうリソースがなければ、初心者向けのガイドを作る知識とモチベーションがある人には大きなチャンスだと思う。jjはすでに無限にユーザーフレンドリーだし、ツールが成熟するにつれて、gitを知らなくても直接jjに行ける新しい世代のプログラマーが出てくるのも不思議じゃないよね。
すぐには分からないな。DAGであることやコミットがあること、gitリモートと互換性があることなど、一定の「gitらしさ」が組み込まれてるからね。業界がまだgitで動いてるから、ほとんどの人はそれなりに学ぶ必要があると思うよ。
正直、JJが1.0になるまでは初心者にはおすすめしないよ。インターフェースにはまだ大きな変更があるからね。
https://jj-for-everyone.github.io/
実際には並行して作業してるわけじゃないんだよね。何かを止めるコストをほぼゼロにしてるだけ。Gitでは、Aを止めてBに切り替えるのにリベースが必要だけど、jjではBを編集するとスタックが再構成されて、そのまま進めるんだ。それが全て。コンテキストスイッチが安くなるから、どんどん切り替えられるんだよね。
jjを試すのは超リスクが低いよ。バックエンドにgitを使ってるから、試してみて問題があったらgitに戻れるし、デタッチドヘッド状態以外のデメリットはない。ぜひ試してみてほしい。どの面でもgitよりずっといいから。スタックやさっき言ったメガマージを簡単に扱えるようになって、作業の小さな単位がレビューやマージされている間も前に進めるんだ。最初にjjを使おうとしたときは、あまり本気じゃなくてjjとgitを行ったり来たりしてたんだけど、最終的にスタックやマージにうんざりして、jjを本気で試してみたんだ。数日間真剣に使ってみることをおすすめするよ。そうすれば本当に理解できるから。戻れなくなるよ。jjのDiscordはとても助けになる場所だし、みんなに感謝してる。素晴らしい記事だね、アイザック!
個人プロジェクトではすごく気に入ってるんだけど、仕事では自作のツールがハッシュに大きく依存してるんだ。だから、スナップショットを作る操作があると、クラウドが完全に混乱しちゃうんだよね。現在のスナップショットに対して正しいコミットにgitを同期させるためのルールや指示を与えようとしたけど、その信号がコンテキスト内で弱すぎると、何が間違ってるのかを理解しようとして壊れちゃうんだ。
> jjを試すのは超リスクが低いよ。バックエンドにgitを使ってるから、試してみてダメだったら、デタッチドヘッド状態以外のデメリットなしにgitに戻れるんだ。ちなみに、他のモダンなバージョン管理システムを試すリスクもほとんどないよ。ほとんどがgitと互換性があって、行き来できるからね。もちろん、mercurialもその中に入るよ。
小さなプロジェクトで試してみたんだけど、Gitで培った筋肉記憶が働いて、JJもそうなるといいなって思ってる。Gitでの失敗を全部経験して、苦労しながらやってきたから、JJを使うときもGitの考え方が頭をよぎるんだよね。今のところ、GitのエイリアスをJJの同等のものにマッピングしたけど、正しいやり方を学んでJJのやり方でやりたいと思ってる。時間がかかるだろうけど、ゆっくり進めるつもり。
この記事はすごく楽しめた!Jujutsu TUIのMajjitに新しいアイデアをもらったよ。 https://github.com/anthrofract/majjit
JJがよくわからないんだよね。投稿されるたびに、JJがすごく複雑なワークフローを可能にするってみんなが絶賛してるけど、俺には理解できない。シンプルなフィーチャーブランチ/リベースのワークフローが何十年も役立ってきたから、なんで(この場合)「オクトパスマージ/メガマージ」で複雑にする必要があるのか理解できないんだ。そうするとリポジトリや履歴を考えるのが難しくならない?
基本的なワークフローにいつも従ってるけど、それでも全然良いよ。
SVNユーザーがgitについて文句言ってるみたいだね。
まだチームの主要なgitリポジトリにマージされていない変更がたくさんあると、jjはすごく役立つよ。常に10〜30個の変更がいろんな状態であるからね。時にはお互いに依存関係があったり、なかったりすることもある。一つのブランチに全部入れることもできるけど、いろんな面であまりエルゴノミックじゃないんだ。jjは、gitが対応できない方法で僕のワークフローに合わせてくれるから、生活が楽になるんだ。正直、魅力を感じなければ使わなくてもいいと思う。多くの人がvimを魅力的だと思わなくてvscodeに留まってるのも全然いいことだよ。
でも、JJはメガマージを簡単にしてくれるんだ… これが現実により合ったシンプルだけど強力なワークフローへの道を開くんだ。複数の収束する変更や、$理由による分離された履歴を持つことが、リバーブやPRの直列化なしで簡単にできるようになる。さらに、より良いコンフリクト解決のおかげで、次のリリースにメガマージを追加するのが実現可能になることが多いよ。
そのワークフローでも、jjはすごく助けになるよ。例えば、いくつかの機能を同時に作業しているときに、関係のない変更が異なる機能ブランチからスタッシュに溜まっていくのにイライラしたことない?それとも、リベースの途中で別のブランチに切り替えたいけど、今の位置を失いたくない時とか。jjの作業コピーをコミットとして扱うモデルと、コンフリクトの一級の扱いが、その痛点を解決してくれるんだ。
Gitがよくわからない。毎回投稿されるたびに、みんなが「Gitは超複雑なワークフローを可能にする」って絶賛してるけど、全然理解できない。数十年使ってきたエディタのシンプルな編集/元に戻すワークフローがあるから、理解できないのかも…。
> JJがよくわからない。毎回投稿されるたびに、みんなが「JJは超複雑なワークフローを可能にする」って絶賛してるけど、これが気になる。スタックやメガマージみたいなものは大きな赤信号で、便利だって言ってる人たちを見ると混乱する。メガマージのアイデアを考えてみよう。もしツールがすべての問題を解決するなら、変更をどうレビューするつもりなの?メガマージが難しいのは、コンフリクトじゃなくて、変更が意味を持つかどうかを確認することなんだよね。
Jujutsuが大好き。どんなブランチやマージの構造を使っても、仕事がシンプルになるから。Gitよりも自分には合ったモデルなんだよね。
10年くらい前に仕方なくmercurialをやめたんだけど、これを読むとちょっと涙が出そうになる。mercurialは今のjjみたいな感じだったんだ。revsetsがあったし、mutableとimmutableのコミットの概念も導入されたばかりだった。absorbもあったし、ブックマークもあった。 "index"はなかったけど、コマンドにはこの投稿で見るような人間が読めるオプションがあった。gitリポジトリとも連携できたし。ああ、懐かしいな。jjを使うのが怖いのは、mercurialみたいにgitに負けちゃうんじゃないかって思うから。でも、すごく魅力的だよね。
gitに負けることはないよ、だってその裏にはgitがあるから。