🫥

Git で add しない運用していたあのファイルを jujutsu (jj) でどう扱うか

に公開2

新しい VCS である JuJutsu (jj) を試しに使い始めました。
Git とは色々と考え方が違って戸惑う点も多いですが、その一つが「Git での add しない運用を jj ではどうやって実現するか」でした。

  • grep の結果をファイルに吐いた
  • サーバーからログを scp で持ってきた

などの理由で、しばらく参照したいけど履歴には残したくないファイルがしばしば表れます。

この記事では、jj でこの手のファイルをストレスなく扱うのに私が採用した方法を記載します。

この記事は私はこうしているという内容でして、jj 公式が推奨している方法ではありません。私はこうしているよ、こうするといいよ、などのアドバイスや意見を歓迎します。


jj と Git の違い

  • Git
    git add しなければ追跡されない
  • jj
    → 作業ツリーの変更は基本すべて changeset に含まれる

つまり jj では add しないという選択肢がありません。


.gitignore は恒久的すぎる

.gitignore / .jjignore を使えば無視できますが、一時的なファイルのためにいちいち .gitignore を編集するのは面倒です。

  • ignore にファイルがあった形跡が残る
  • 一時的なファイルが消えたら ignore を戻す必要がある
  • 忘れそう

あたりが嫌すぎます。


私の solution: scratch/ ディレクトリを作る

一時ファイル専用の置き場 scratch/ をプロジェクト内に作ることにしました。

ディレクトリ構成

scratch/
  .gitignore
  README.md

scratch/.gitignore

*
!.gitignore
!README.md

scratch/README.md

# scratch

This directory is for local investigation artifacts.
Files here are intentionally not tracked.

これで以下のようになります。

  • scratch/ 配下のファイルは追跡されない
  • README.md で意図が伝わる
  • ignore を「戻す作業」が不要

「いつ移動すればいいの?」問題

jj new する前に scratch/ に移動しておくことが重要です。

# 正しい手順: 最初から scratch/ に置く
scp server:/var/log/app.log scratch/
jj new  # scratch/ 内なので changeset に含まれない

もし以下のように scratch/ の外に置いてしまった場合は、changeset に入ってしまっているため、何らかの方法で戻す必要があります。

# うっかり scratch/ の外に置いてしまった場合
scp server:/var/log/app.log .
jj new
mv app.log scratch/

この場合は:

jj restore app.log
# or
jj file untrack app.log

jj 面倒、という気が一瞬してしまいますが、Git であれば、Git 管理したくないファイルを commit してしまったのと同じような状況と考えれば、まあこれくらいは仕方ないのかなあと思います。Git よりうっかりしてしまいそうな点ではありますね。


まとめ

  • jj には add しない運用がない
  • 一時ファイルは置き場ごと分離した
  • scratch/.gitignore
    • 忘れない
    • 共有できる
    • jj / Git 両対応

scratch という名前は、"scratch pad", "scratch space" という英語の慣用表現から AI に提案してもらいました。

他に、よきソリューションがあれば教えてほしいです。

Discussion