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

忙しい開発者のための呪術

概要

Anubis はウェブサイトをAIによる スクレイピング から守るための Proof-of-Work 方式の保護システム。 個人利用には影響が少なく、大量アクセス時に負荷をかける設計。 Hashcash に着想を得た仕組みで、メールスパム防止技術を応用。 将来的には ヘッドレスブラウザ の識別強化を目指す。 特定の JavaScriptプラグイン が動作を妨げる場合がある点に注意。

Anubisによるウェブサイト保護の仕組み

  • Anubis はサーバーをAI企業による 過剰なスクレイピング から保護するために導入
  • 一般ユーザーには Proof-of-Work 課題を課すことで、アクセスを制限
  • Hashcash 方式を参考にした設計で、個人利用時の負荷は最小限
  • 大量スクレイピング時には 計算負荷 が蓄積し、コスト増加
  • 一時的な ダウンタイム やリソースの不可用性の防止策

今後の開発方針と注意点

  • 現状は 暫定的な対策 としてProof-of-Workページを表示
  • 将来的には フォントレンダリング等の特徴 でヘッドレスブラウザの識別強化を計画
  • 正規ユーザーにはProof-of-Work課題を省略できるよう改善予定
  • JShelter などの一部JavaScriptプラグインがAnubisの動作を妨げる場合あり
  • 不具合時は該当プラグインの 一時無効化 を推奨

Anubisのバージョン情報

  • 現在の Anubis バージョン: v1.20.0

Hackerたちの意見

チームをジュジュツに移行しようと頑張ってるんだけど、なかなかうまくいかないんだ。やっぱり、gitの一般的だけど複雑な操作をわかりやすく示したページがあればいいなと思ってる。ここでのエレベーターピッチみたいな感じで、スティーブのチュートリアルほど深くなくていいから、もう少し詳しく説明してほしい。もしかしたら、デモをやってみて、みんなに見てもらって質問してもらうのがいいのかもしれないね。

gitはあんまり好きじゃないんだよね。ずっとmercurialを使ってたし。でもそれは10年前の話。今じゃgitが頭に染みついちゃってる。全体的にはまあまあうまくいってるけど、Jujutsuが本当に時間をかける価値があるほどのメリットを提供してるかはよくわからない。初期設定の面倒くささ(例えば、見にくい色とか、自分好みのスクリプトやエイリアスを設定すること)を考えると、余計にね。

操作のリストは多くないけど、jjとgitの一般的な操作の比較が、私にはピンときたんだ。 https://lottia.net/notes/0013-git-jujutsu-miniature.html

いいアイデアだと思うのは、gitの一般的だけど複雑な操作をちゃんと見せて、jujutsuではどれだけ簡単になるかを示すページだね。実際、一般的なgitの操作がjujutsuで簡単になるわけじゃない。時にはgitのバックエンドとの不整合のせいで、ちょっと難しくなることもある。むしろ、gitではほぼ不可能、もしくは非常に不便な操作をjujutsuでは簡単にできるんだ。だから、あまり誰もやらないことになる。これを説明するのが難しいのは、みんなが「そんな新しいワークフローがあるよ」って言っても、彼らは「必要ない」と思ってるから(代替手段があるし)、プログラミングが得意な人にはその考えが嫌悪感を引き起こすんだよね。

これがあなたが探しているかもしれない素晴らしいリンクだよ https://v5.chriskrycho.com/essays/jj-init/ https://v5.chriskrycho.com/journal/jujutsu-megamerges-and-jj... https://ofcr.se/jujutsu-merge-workflow

次の部分、きっと気に入ると思うよ!別に投稿されると思うけど、ここにリンクしてあるページの下の方にも載るはず(早ければ数日以内にね)。

自分がちょっと鈍いなって感じるのは、自動的に変更をリビジョンに追加することがまだうまく理解できてないから。開発中に使うファイルをローカルで変更することがあるんだけど、その変更をコミットするつもりは全然ないんだ。普通のgitでは、そのファイルをステージしないから、リモートリポジトリに誤って変更をプッシュする心配はないんだけど、jjではその変更をどうにかしてアンステージしないといけないみたい。習慣の問題かもしれないけど、すべてをデフォルトでコミットするんじゃなくて、自分がコミットしたいものを明示的に言いたいんだ。もしかして、jjを完全に誤解してるのかな?

このワークフローが欲しいなら、jjの@(gitのHEADに相当)をgitのインデックスとして扱って、コミット時に手動で@-に変更をまとめるといいよ。git add --patchと同じ感じでね。

それは正しいよ、そしてそれをやめようとしてる習慣でもある。合理的な考え方は、追跡されていない状態でコードを実行するのはやめるべきだってこと。変更が重要ならコミットすべきだし、そうじゃなければコミットしない方がいい。そうしないと、開発中に実際には存在しなかったコードのバージョンを記録することになるからね。これが特に厄介なのは、リポジトリ全体の設定とローカル専用のバージョンを区別しないツールがあるから。VSCodeは大きな問題で、‘launch.json’しかなくて、ホストごとのカスタマイズに適した‘launch.local.json’がないんだ(例えば、ポート8888で何かをすでに実行しているから9000にマッピングする必要があるってこと。だから、環境の quirks をコミットするべきじゃないよね)。

jjでは、変更を分けるためにjj splitを使うことが多いよ。選択した部分が最初のリビジョンになって、残りの部分が2番目のリビジョンになるんだ。たくさん作業してから、小さくて扱いやすいリビジョンに分けることが多い。もし独立した作業のスレッド(例えば、他の場所のバグ修正やドキュメントの修正)なら、並行リビジョン(別のブランチ)に分けることもある。jjでは明らかにワンライナーだけど、gitでは面倒なブランチ切り替えやスタッシングが必要になる。git addスタイルのワークフローも使えるよ。jj newで新しいリビジョンを作成して、もう一度やって、変更を加えたら、jj squash -i/--interactiveで含めたい部分を選ぶんだ。変更を続けて、満足するまで前のコミットにまとめていけばいい。概念的には、@(現在のリビジョン)と@-(前のリビジョン)をそれぞれ作業コピーとステージされたコピーとして考えてみて。

普段は作業してから、jj splitでコミットしたい変更をレビューするんだ。これでワークフローはgit add -pみたいに見えるよ。良いメンタルモデルは、最上部のコミットはどこにもプッシュされないことが多いってこと。作業コピーみたいなもので、スタッシングも「無料」でできる(新しいコミットを作るためにメインに戻る?すべてのWIPはそのブランチに残るから、メインに持ち越されない!)。

jjの自動ステージングは、必ずしも望ましいわけじゃないね。jjのドキュメントや宣伝者たちは、デフォルトで簡単にオフにできるってことをもっと明確にすべきだと思う。これを~/.jjconfigに追加すればいいんだ:[snapshot] auto-track = "none()"

jjを使い始めて2週間になるけど、すごくワクワクしてる。初めてコマンドラインだけでバージョン管理を使うのに慣れたから。GitではいつもGUI(できればVSCodeのGit Graph)を使って、アイテムを右クリックして操作を始めてたけど、jjはシンプルで一貫性があって、スティーブ・クラブニックのチュートリアルを読んだ後すぐに使い始められたんだ。今直面しているのは、revset言語を本当に学ぶべきだってこと。そうすれば、jj logからIDをコピー&ペーストする必要がなくなるから。

同じコピー&ペーストの問題があったけど、今はjjui(https://github.com/idursun/jjui)を使ってる。日常の操作がさらにスムーズになって、ログの上を飛んでるみたいだ。

俺も似たような状況だよ:長い間gitを使ってきたけど、もっと複雑なことはいつも何らかのUI(たいていはintellij)を通してやってた。約1ヶ月間、特に問題なくjjを使っていて、CLIを使うのが快適になってきて、徐々に複雑な操作にも慣れてきてる。ドキュメントはまだ多くの前提知識を必要とするから、時々ちょっと難しいんだ。こういうブログ記事を見るのが好きで、もっと深いリソースが時間とともに出てくることを期待してる。スティーブのガイドは良いけど、まだ自分にはギャップがあるな :) 次はもう少しrevset言語を学んで、リベース操作にもっと慣れたい。シンプルなCLI、コンフリクト解決、オペレーションログが大好きだ!

jjを数週間使ってて、最近自動コミットメッセージスクリプトを作ったんだ[1]。今日、古いgitリポジトリで作業を始めて、そのスクリプトをgitに移植すべきだと思った。実際、jjのおかげでスクリプトが簡単になったんだ。イミュータブルコミットのおかげで、gitでは自動的にそれをやらなきゃいけない。仕事ではリベース/修正/履歴クリーンのワークフローを使ってるから、スクリプトがいつコミットするか、いつ修正するかを判断する必要がある。もちろん可能だけど、そんなに手間をかけたくないんだ。だから、jjで再クローンしたよ。コミットと修正の小さな違いをどれだけ早く忘れたか、驚いてるよ。[1]: https://codeberg.org/jcdickinson/nix/src/branch/main/home/co...

再クローンする必要すらないよ。既存のgitリポジトリにjjを追加できる。

jjを学ぶ価値があるかどうか迷ってる人に言いたいことがある。Hacker Newsで話題になると、だいたい二つのグループに分かれるんだよね。まだ試してない人と、推してる人。1週間使ってみてgitに戻った人はほとんどいないと思うよ。切り替えたけど惰性でそのままって人もあまり見ないし。もちろん、そういうこともあるけど、例外だよね。私の経験から言うと、真剣に試した人は100%切り替えてる。今日は試してみる日だと思ってほしい。切り替えるのは思ってるよりずっと楽だよ。切り替えたその日から生産的だったし、1週間以内にはgitコマンドに戻る必要がなくなった。すぐに生産性が上がるし、これなしでどうやってやってたのか不思議に思うようになるよ。

gitが好きな理由は、使ってる機能が2%くらいだから。bisectとか使わなきゃいけないっていう宣伝には騙されないよ。99%のgitコマンドは3文字にエイリアスしてるから、専門用語の多さも気にならない。

反論として、Google内部で導入したんだ(Piperのバックエンドがあるから、GoogleのモノレポのPerforceみたいなやつ)。日常の仕事はモノレポではやってないけど、週に1、2回は入るよ。既存のフロントエンド(Mercurialベース)が遅いからJJを使い始めたんだけど、JJは速いんだ。いい感じで、本当に気に入ってる!最終的にはメインのVCSに切り替えるかも。でも、そこまで重要だとは感じてない。メインの仕事は面倒なリベースが多いけど、JJが本当に輝くところだしね。なんでだろう、a) gitを完全にマスターしてて、深く根付いたワークフローがあるから、b) プロジェクトが面倒なリベースを含んでるにも関わらず、バージョン管理は私の問題リストの中ではそんなに重要じゃないから。だから、JJの技術には期待してるけど、Gitからの移行は遅くて着実になると思う。

IDEでgitサポートは使ってるけど、jujutsuは使ってない?俺はintellij使ってるけど、どれだけ役に立つかはわからないな。

jjを数ヶ月使った後、結局gitに戻った。最大の理由はパフォーマンスだね。jjの操作は数秒かかるのに対し、gitはプロジェクトの大きさに関係なく瞬時に反応する。今はこれが修正されているかもしれないけど、正直言ってjjを使うのは少し精神的な負担があったと感じてた。gitに戻ったときは、肩の荷が下りた気分だった。多分、10年間の継続的な使用のせいかもしれないけど。

一般的に二つのグループの人がいる:まだ試していない人と、それを熱心に勧める人。これはまさに、熱心に勧める人が言いそうなことだね。

試してみたけど、結局は切り替えなかったよ。面白いことに、最初から自分が使ってるのとほぼ同じ方法でgitを使わされてるって気づいた。もう15年以上gitを使ってるからね。最初の1年以降は「リポジトリを削除して再クローン」なんてことは一度もなかった。つまり、実際にgitを理解してるから、Jujutsuはあんまり必要ないんだ。あと、git用のすごく良いツール、つまりMagitも使ってるしね。個人的には、Magitの方がJujutsuよりもずっと優れたgitのフロントエンドだと思う。正しい道に導いてくれるけど、gitの力を奪うことは全然ない。かなり素晴らしいよ。もしかしたら、同僚にjjを勧めるべきかも。でも、問題は、もう彼らにgitを手伝う約束をしちゃってるから、jjの経験がないんだよね。

「jjを学ぶ価値があるかどうか迷ってる人には、1週間使い続けた人を見つけるのは難しいでしょう。」報告します。最終的にjjを使うことになるかもしれないけど、今のところはしばらくするといつもgitに戻ってる。私にとっては、ステージングエリアとそれによって可能になるワークフローが重要なんだ。ほとんどの人はこれを嫌って、jjがそれを排除するから好きなんだろうけど、私はそうじゃない。ステージングエリアは、余計な技術的制約を克服するために必要なハックだとは思ってなくて、ワークフローツールだと思ってる。私が考え方を変えることはできるか?もちろん。今のところjjには十分なメリットが感じられなかったけど、いつかもう一度試してみるつもりだよ。

VCSのUIの分野では確かにしっかりした改善だけど、jjには現在の制限があって、特にgitのパワーユーザーには切り替えを妨げるかもしれないから注意が必要だよ。gitattributesのサポートがないから、git-cryptやgit-lfs、フィルターが必要なものは使えないし、行末設定が無視されるからWindowsとの互換性がちょっと悪くなる。あと、git-annexやgit-bugみたいな補助ツールも二流になっちゃう、つまりoplogの統合がないし、内部用のコミットやヘッドでログがぐちゃぐちゃになるかもしれない。

「jjを学ぶ価値があるかどうか迷ってる人には、1週間使い続けた人を見つけるのは難しいでしょう。」 私はgitに関して生産性の問題は全くないよ。毎日1時間gitコマンドを実行してるわけじゃないしね。確かに、日中ずっとgitでリポジトリを操作してる人もいるだろうし、そういう人にはjjの方がいいかもしれない。でも、私の場合はそうじゃないし、gitはもうどこにでもあるから。私にとっては、「bimに移行しなきゃダメだ、より良いvimだよ。vimに似てるけど、新しいことを学ばなきゃいけないほど違う。だけど、bimを始めるとすぐに編集モードに入るから、iをタイプする必要がない!それに、Juliaのオートコンプリートはbimの方が客観的にずっと良い!」って言われてるように聞こえる。確かに、iを数回タイプするのは全然気にならないし、Juliaも使ってない。でも、もしそれが君にとって良いなら、bimを楽しんでね!

真剣に試した人たちからは100%の転換率を見たことがある。認知的不協和ってやつだね。

これって何なのか混乱してる。gitに混乱してる人のためのgitフロントエンドなの?バックエンドを抽象化してるって書いてあるけど、どうしてこんなにgitに影響されたものが、PerforceやPiperみたいな中央集権型システムに合う抽象化を持てるのかが不明。デザインの決定もあまり良くないし。作業コピーをコミットとして扱うのは、品質管理がないってことだよね。コミットの本来の意味は…コミットすることだから。だから、実際にコミットしたい変更から無駄な変更を取り除くために、別のリポジトリやフィルターが必要になる。悪いコミットがgitの履歴を汚すのは大きな問題だし。私の意見では、gitの最大の問題はスケールが悪いことと、コミットの汚染を助長すること。おそらくjjはその問題に取り組んでないんだろうけど、それは全然構わない。でも、どの問題に取り組んでるのかが混乱してる。だから、著者が自分の好みに合ったフロントエンドだと思ってるのか気になってる。

作業コピーをコミットとして扱うのは、品質管理がないってことだよね。作業コピーは自動的にGitHubにプッシュされたり、そんなことはないよ。説明をつけるときにコミットをレビュー/キュレーションするんだ。

バックエンドを抽象化してるって書いてあるけど、どうしてこんなにgitに影響されたものが、PerforceやPiperみたいな中央集権型システムに合う抽象化を持てるのかが不明。Piperのバックエンドは正直、Gitのバックエンドよりも良く機能してる。これはGitのバックエンドを否定するものじゃないけど、インピーダンスミスマッチがひどい。 > デザインの決定もあまり良くないし。作業コピーをコミットとして扱うのは、品質管理がないってことだよね。コミットの本来の意味は…コミットすることだから。だから、実際にコミットしたい変更から無駄な変更を取り除くために、別のリポジトリやフィルターが必要になる。悪いコミットがgitの履歴を汚すのは大きな問題だし。ごめん、でもこれを言うってことは、試してないってことだよね。:-) JujutsuのコミットはGitのコミットとは同じじゃない。Gitのバックエンドを使ってるなら、GitのコミットとGitの作業ツリーの組み合わせで実装されてるけど、'commit'を見たら'名前付きdiff'として読んでほしい。Jujutsuには不変のコミットの概念もあって、デフォルトでは(大体)上流にプッシュされたコミットを意味する。プッシュする前に、プッシュされていないコミットを履歴をきれいにするために書き換えることができるし、すべきだよ。jjは、gitのリベースや履歴編集よりもずっとずっと簡単にそれを実現できる。私の非自明なjjの作業は、実験からドキュメンテーションブランチまで、少なくとも3、4回のコミットが関わることが多い。これをgitでやると、ストッシュや不便な使い捨てブランチに無理やり収めなきゃいけなかったんだ。

これって何なのか混乱してる?jjはバージョン管理システムだよ。バックエンドに依存しないんだ。最も一般的なバックエンドはgitだけど、gitが人気だからね。これにより、jjをgitリポジトリで使えるから、チームメンバーに強制することなく個人が導入できるんだ。 > これは、gitに混乱している人のためのgitフロントエンドなの?俺はgithubが存在する前からgitを使ってた。jjを見つける前は自分をgit好きだと思ってたけど、もうgitには戻らないよ。jjはgitよりもシンプルでありながら、同時にパワフルなんだ。gitに混乱している人はそのシンプルさが好きかもしれないけど、俺はその力が好きなんだ。 > バックエンドを抽象化しているって言ってるけど、gitに影響を受けたものが、PerforceやPiperのような中央集権的なシステムとどうやって連携するのかは不明だね。自動インクリメントの数値コミットがあるし。これについてはもういくつか返信があるから、そっちに任せるよ :) > デザインの決定の中にはあまり良くないものもある。作業コピーをコミットとして扱うと、品質管理がなくなる。コミットの本来の目的は...それをコミットすることだからね。だから、無駄な変更を実際にコミットしたいものから取り除くために、別のリポジトリやフィルターが必要になる。悪いコミットがgitの履歴を汚すのはすでに大きな問題だ。これは理解できる誤解だね。正しい考え方は「インデックスもコミットだ」ということだ。jjを使う一般的な方法は、こんな感じだよ:例えば、コードベースに機能xを追加する作業をしていると想像してみて。まず変更を加えて、説明をつけるんだ:jj new -m "機能xに取り組んでいる" trunk 作業コピー(@)は今:lqqlysul c6756b49(空)機能xに取り組んでいる 親コミット(@-):ylnywzlx 8098b38d trunk |(空)foo さて、これに新しい空の変更を追加する:jj new 作業コピー(@)は今:pxrvoron c823d73a(空)(説明なし) 親コミット(@-):lqqlysul c6756b49(空)機能xに取り組んでいる さて、@-は公開するつもりの変更だけど、@は俺のインデックスだ。foo.rsを追加するとする:touch foo.rs さて、jj statusを実行すると、jjがスナップショットを取って、@にそれが保存される:jj st 作業コピーの変更:A foo.rs 作業コピー(@):pxrvoron ba7ad8c6(説明なし) 親コミット(@-):lqqlysul c6756b49(空)機能xに取り組んでいる ここでjj diffを使ってdiffを見ることができる:jj diff 追加された通常のファイル foo.rs:(空) じゃあ、内容に満足したとしよう。最終的なコミットにステージングしたい。これをjj squashでできるんだ。デフォルトでは、@の全てのdiffを@-に入れる:jj squash 作業コピー(@)は今:pxkqmsww 9f7e1ef2(空)(説明なし) 親コミット(@-):lqqlysul 41dc1531 機能xに取り組んでいる これで変更は@ではなく@-に入った。-r(リビジョンのため)をjj diffに渡すことで確認できる:jj diff -r @- 追加された通常のファイル foo.rs:(空) 変更全体を移動する必要はない。jj squash -iを使えば、git add -pと同じことができて、diffの一部だけを移動できる。ここでの利点は?インデックスがただのコミットだから、コミットで使うツールをインデックスでも使えるんだ。git resetのように--hard--soft--mixedを使ってインデックスの動作を扱う必要はない:全てがコミットに入っているから、全てが一貫して動作する。jjはコミットを正確に自分が欲しいものに分割するのをとても簡単にしてくれる。インデックスを同じ目的で使うよりもずっと簡単でパワフルなんだ。 > gitの最大の問題は、スケールが悪いこととコミットの汚染を助長することだと思う。おそらくjjはこれらの問題に取り組んでいないんだろうけど、それは全然問題ないよ。でも、どの問題に取り組んでいるのかは混乱してる。だから、著者が自分に合ったフロントエンドを見つけただけなのか疑問に思ってる。個人的には、コミットの汚染はgit自体よりもプルリクエストのワークフローによるものだと思うけど、gitがあまり助けになっていないのも事実だ。jjはこういうことに役立つけど、ある程度は限界があると思う。

jjについて私をイライラさせる主な点は、すべての変更が常に暗黙的にステージングされることだよ。これは昔のSVNがやってたことで、gitは変更を明示的にステージングすることで大きな改善をもたらした。私のリポジトリには、次のコミットに含めたい変更よりも多くの変更がほとんど常にある。gitなら、含めたい変更だけを追加すればいい。jj(とsvn)では、明らかな回避策がなくて、コミットする前にリポジトリの外に変更を手動でコピー&ペーストしなきゃいけない。

jj commit -i(または多くのコマンドで-i)と、設定でsnapshot.auto-track="none()"を使ってる。実際には、あまり関係のないファイルやチャンクをそのままにしておくabsorbもよく使ってる。

自動スナップショットを無効にするか、ほぼ専ら使ってるjj split -iを使うといいよ。

jjを数日試してみたけど、lazy gitを使った自分のワークフローやスクリプトで十分生産的になってるから、別の思考モデルを扱う必要はないかな。jjは全体的にクールだけど、もしこれからバージョン管理を始めるならいいかもしれない。でも、私たちのような年配の人には、変わるための十分なモチベーションにはならないね。

うーん、GitButlerを使ってるなら、ポーセリンはあんまり関係ないってのは分かるけど、数日前にJujutsuを試してみることにしたんだ。Claudeにいくつかのこと(コミット、ブランチの移動、Githubへのプッシュ/プル)をどうやってやるか聞いたら、Jujutsuをマスターするのに10分もかからなかったよ。今ではこれが自分の選ぶVCSになってる。diffが改善されてるからLazygitも使ってるけど、常にdetached HEADにいるのが気にならなければ、全然問題ないよ。JJはgitとちゃんと連携するけど、JJで同じことをもっと簡単にできるのに、なんで難しいgitコマンドを使う必要があるの?それに、未コミットのファイルを持ったままブランチを移動できるのは神の恵みだね。今は、やりたいコミットを編集するだけで、機能開発、バグ修正、コピー変更なんかをスムーズに行き来できる。もし複数のAIエージェントにその作業をさせたいなら、ワークツリーを作って進めるだけ。変更を説明(基本的にコミットメッセージを追加)できるのもすごく気に入ってるから、ツリーの中で確認できるし。JJは本当に素晴らしいよ。

ちょっと試してみたけど、git-branchlessに戻ったよ(https://github.com/arxanas/git-branchless)。git-branchlessはgitリポジトリで作業するためのツールセットが優れてるから、JetBrainsのgit統合みたいなローカルツールも問題なく動く。Jujutsuと似た哲学で(コミットツリーを簡単に操作できるようにする)、作者たちはお互いにアイデアを交換してたみたい。

彼らが「アイデアを交換した」以上のことがあるみたいだね。git-branchlessのリード開発者であるArxanasは、jjの主要な開発者でもありメンテナもしてる。彼はjjのディスコードでもアクティブで、先月にはGit Merge 2025の際にjjのサイドカンファレンスをGithubで呼びかけてたよ。