2 ポイント 投稿者 GN⁺ 15 일 전 | 1件のコメント | WhatsAppで共有
  • Jujutsuのコマンドラインインターフェースであるjjは、**分散バージョン管理システム(DVCS)**ベースのツール
  • gitよりシンプルで直感的でありながら、より強力な機能を提供
  • gitとMercurialの長所を組み合わせ、中核ツール数を減らし有機的な連携を強化
  • git互換バックエンドを使用し、既存の協業環境を維持しながら独立した実験が可能
  • 上級ユーザーにとって、gitでは難しい追加のバージョン管理機能を活用できる点が重要

jjの紹介と特徴

  • jjはJujutsuのCLI(コマンドラインインターフェース)であり、Jujutsuは分散バージョン管理システム(DVCS)

    • ユーザーはgitのような他のDVCSに慣れているかもしれず、このチュートリアルはgitユーザーの視点を前提としている
    • jjは、gitよりシンプルで使いやすく、それでいて強力なツールとして設計されている
    • 一般に「強力さ」と「複雑さ」は相反するが、jjはこのバランスを新しく提示する
    • jjは**gitとMercurial(hg)の長所を組み合わせ**、新しい形のDVCSを構成する
    • 中核ツール数を減らし、各ツール間の有機的な連携によって効率的な作業環境を提供
    • 上級ユーザーは、gitでは難しい追加のバージョン管理機能を活用できる
    • jjは**git互換バックエンド**を使用し、協業環境を変更せずに独立した実験が可能
    • 既存のgitリポジトリとの互換性を維持しつつ、必要に応じて容易にgitへ戻ることも可能
    • チュートリアルは、こうした特性を通じてjjなぜ注目に値するツールなのかを直接示す過程を予告している

1件のコメント

 
GN⁺ 15 일 전
Hacker Newsのコメント
  • 議論の多くは gitとjjの違い に集中しているが、私はgitのことはいったん忘れて、jjの基本ワークフローに集中したほうがいいと思う
    クリーンなリポジトリで jj を実行すれば状態を確認でき、変更後に jj commit -m "made changes" でコミットすればよい
    ミスしたときは修正してから jj squash で最後のコミットにまとめればよい
    新しいブランチのように特定のリビジョンから作業したいときだけ jj new -r lmnop を使えばよい
    gitの履歴は git log で確認でき、jjの内部動作は見えない

    • 私も似たようなことをしたくて、alias.save="!git add -A; git commit -m" のような git alias を作り、$ git save "made changes" のように使っている
  • JJは私に 逆向きに考えろ と要求しているように感じる
    gitでは変更後にコミットメッセージを書くが、jjでは先に新しいコミットを作って説明を付ける形だ
    複数の機能が混ざった汚い状態から必要な変更だけを選んでコミットするのに慣れているが、jjのチュートリアルを見る限り、それが可能なのか確信が持てない

    • jj new は空のgitステージング領域のような概念だ
      jjでは常にコミットが存在し、そのコミットはフォルダ内容に基づいて計算された値として 安定したchangeid を持つ
      複数の変更を分けてコミットしたいなら jj split を使えばよい
    • 私はよく jj new で一時コミットを作り、メッセージは空のままにしておく
      あとで準備ができたら複数のコミットを squash して1つにまとめ、メッセージを追加する
      このやり方は一種の undo履歴 のように機能するので、実験がずっとやりやすい
    • 実際のところ jj new は単に「上に新しいコミットを作る」だけなので、すぐに説明を書く必要はない
      私も最初は習慣づけようとしたが、かえって非効率だった
    • JJではこうしたやり方が 標準的
      Gitでも似たワークフローが推奨されてきたし、Squash Workflow を見るとGitのインデックスに近い流れを作れる
    • 私もいろいろ変更していると、別々の機能が混ざってしまうことがある
      だから複数のワークスペースを用意し、shelve 機能(IntelliJ)をよく使っている
      ときにはgitパッチでdiffを一時保存しておくこともある
      こうした混沌とした過程を同僚には見せず、少しでも プロフェッショナル に見せようとしている
  • jjを使ってみて気に入らない点は、ファイル修正が自動的にコミットされることだ
    過去のコミットをたどろうとしてcheckout後にファイルを修正すると、そのコミットが変わり、その後の履歴が全部リベースされる
    だから防衛的に空コミットを新しく作らなければならない
    gitは明示的にコミットするまではリポジトリが変わらないので、そのほうが楽だ

    • 私も以前はそう思っていたが、jj evolog を知ってから考えが変わった
      jjはステージングより優れた解決策をすでに持っていた
      git CLIに慣れていることが、むしろjj学習の 障害 になっていた
      興味深いことに、jjを使うとgitの 保存エンジンの構造 をよりよく理解できる
    • edit の代わりに jj new を使えば、きれいに変更を追跡できる
      gitのstashをやりくりするよりずっといいと感じる
    • jj edit はjjの 最大の落とし穴
      代わりに jj new を使い、ミスしたら jj undo で復旧できる
      jjはコミットを安価な スナップショット として扱うので、コミットより「変更」に集中するのが正しい
      自動リベースはpush後には不変として固定されるので安全だ
    • ファイル修正が自動コミットされるのはjjの 中核機能
      jj newjj squash を組み合わせれば、gitのブランチヘッドのように管理できる
      detached head状態での作業をjjは簡単にしてくれる
    • おそらく jj edit で過去のコミットをcheckoutしたのだろう
      jj new に切り替えれば問題は解決する
  • jjの最後の段落が核心だ
    gitと 完全互換のバックエンド を使っているので、チーム全体が切り替えなくても自分ひとりで試せる
    気に入らなければいつでもgitに戻れる

    • ただし、LFSやsubmodule、hookを使う組織では例外だ
    • 完全な互換ではない。相互運用は可能だが 完全になめらかではない
      gitの操作はjjのログに記録されないため、手動でimportしなければならない
      プロジェクトでは1つのインターフェースだけを使うことが勧められている
    • 以前は私もgitをCVSやSubversionと一緒にそうやって使っていた
    • しかしgitとjjを 同じディレクトリで同時に 使うと壊れる可能性がある
  • 私がいちばん好きな機能は jj absorb
    現在のリビジョンの変更を、関連する過去のコミットへ自動的に移してくれる
    設定ファイルや .gitignore の修正を忘れたときに便利だ
    jj new の後に変更して jj absorb すればよい
    しかも merge conflict を扱わなくてよいのが最高だ

    • もし jj absorb が誤って適用されても、jj undo で戻せる
      この機能のおかげで複雑なrebaseも怖くない
    • 参考までに、gitにも git absorb がある
  • チュートリアルは長いこと更新できていないが、今でも毎日jjを使っている
    スタートアップ ersc.io で忙しく、upstreamへの作業ができていなかった
    質問があればいつでも歓迎だ

    • gitとjjの DAG不変性の違い が核心だ
      jjはstable change IDを、gitはimmutable commit IDを使う
      そのためjjでは undoやrebaseがずっと柔軟 に感じられる
    • jjは「面白くない」変更を自動的に隠してくれる
      ときどきもっと多くの変更を見たいことがあるので、それらをまとめて表示するオプションがあるのか気になる
  • jjはgitと違うからこそ試してみる価値がある
    別のアプローチを体験するだけでも エンジニアリングの視野 が広がる
    何もかも試す必要はないが、さまざまなワークフローの トレードオフ を理解するのは重要だ

    • もちろん、99%の場合 得るものの少ない試み は時間の無駄かもしれない
  • gitとjjの関係は CとPython の関係のように感じる
    gitはフォレンジックな追跡で、jjは 物語の章(chapter) のようだ
    ときには前半の章を書き直したほうが、後半がより自然になることがある

    • jjがやっていることはgitでも可能だが、gitの 習慣的な思考様式 が邪魔になる
      jjは「working tree自体がコミット」であり、「conflictもコミットできる」という哲学で設計されている
  • 「より強力で簡単だ」という主張には 具体例 が必要だと感じる

    • jjの利点をいくつか挙げるなら:
      • rebase/merge conflictを即座に解決しなくてよい
      • コミット操作が非常に簡単(特に jjui 使用時)
      • jjはgitの状態変化を追跡する operation log を持っている
      • 名前のないブランチのおかげで実験的な作業がしやすい
      • gitと完全互換なのでチーム内で混在させて使える
    • 私たちはSVNからgitに移ったとき大きな改善を感じたが、今のgitワークフローには大きな不便はない
    • 1つのリポジトリで複数のPRを同時に作業し、それぞれに合わせてpushできる
      こうした必要がなければ、jjの価値を感じないかもしれない
    • jjの魅力はコマンドではなく 直感的なワークフロー にある
      実際に使ってみないとわからない
    • jj undo ひとつだけでも十分価値がある
      gitでは復旧不能な状態になりやすいが、jjなら数回のundoで解決できる
  • jjのおかげで 非線形DAG を活用する自信がついた
    複数の親や子を持つ変更を自由に扱える
    以前は不要に順序を強制していたが、今では 依存関係を明確に表現 できる
    レビューや提出のプロセスもずっと効率的だ

    • こうした分岐した変更の上で mega-merge + absorb ワークフローを使っているのか気になる