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

Claude Codeはプロジェクトリポジトリに対して10分ごとに「git reset --hard origin/main」を実行します

概要

  • Claude Codeが 10分ごとに自動的にgit fetch origin + git reset --hard origin/main を実行
  • 未コミットの変更がサイレントに破棄 される現象を確認
  • アンマネージドファイルやworktreeは影響を受けない
  • 外部gitプロセスは起動せず、内部ライブラリで処理
  • 回避策・関連バグ報告・技術的根拠を詳細に解説

Claude Codeによる10分ごとの自動gitリセット問題

  • Claude Code v2.1.87 (Homebrew cask, Bunバイナリ) 環境下で発生
  • macOS 15.4 (Darwin 25.3.0, arm64) 上で検証
  • zshシェル 使用状況
  • ユーザープロジェクトリポジトリで10分ごとに下記操作が自動実行
    • git fetch origin
    • git reset --hard origin/main
  • 外部gitバイナリは一切起動せず、内部APIやlibgit2のようなライブラリ経由で処理
  • trackedファイルの未コミット変更が消失、untrackedファイルは残存
  • worktreeは完全に影響を受けない (reflogにreset履歴なし)

再現・証拠

  • git reflogに10分間隔でreset: moving to origin/mainエントリが記録
  • src/lib/api.ts(tracked)を変更し、.canary-test.txt(untracked)を新規作成
    • 10分タイマーでapi.tsの変更のみ消失、untrackedファイルは無事
  • fswatchで.gitディレクトリのロックファイル作成・削除を検知
    • git fetch + reset --hardの典型的パターン
  • lsofでClaude Codeプロセスのみが対象ディレクトリで動作
  • 0.1秒間隔のプロセス監視で外部gitプロセス未検出
  • worktreeのreflogにはreset履歴ゼロ

排除した外部要因

  • Git hooks :全て未使用(.sampleのみ)、husky/lint-staged等なし
  • Claude Codeユーザーフック :peon-ping(音声)以外なし、git操作なし
  • プラグインマーケットアップデータ :削除後も現象継続
  • macOSクラウド同期 :対象外ディレクトリ(iCloud, Dropbox, Syncthing等未使用)
  • Cron/LaunchAgents :該当設定なし
  • Vite/SvelteKit devサーバー :出力先のみ書き込み、git無関与
  • IDE/エディタ :nvimは別リポジトリ、format-on-save等無効
  • Time Machine :APFSローカルスナップショットは読み取り専用
  • ファイルウォッチャー :fswatch/entr/watchman/guard等未稼働

バイナリ解析(部分的)

  • /opt/homebrew/Caskroom/claude-code/2.1.87/claude
    • hg1()関数が["fetch","origin"]を実行
    • io1()関数はgit pullラッパー
    • fileHistory stateでtrackedFiles管理
    • setInterval等のタイマーは難読化・最小化コードで特定困難

影響

  • main working treeのtrackedファイル未コミット変更が10分ごとに消失
  • コミット済みの変更には影響なし(resetはno-op)
  • 作業中に変更が何度も消されるため、原因特定まで再適用を強いられる

回避策

  • git worktreeを利用 :reset対象外で安全
  • 頻繁にコミット :コミット済み変更は消えない

関連バグ・報告

  • #8072 :「Critical Bug: Code Revisions Being Repeatedly Reverted」
  • #7232 :「CRITICAL: Claude executed git reset --hard without authorization causing data destruction」
  • #32793 :「claude install corrupts project git remote URL」(本件とは別件)

Claude Code開発チームへの質問

  • 内部で600秒ごとにprocess.cwd()に対してgit fetch origin + git reset --hardを実行する仕組みは何か?
  • バイナリ難読化・sudo権限なしのため詳細なプロセストレース不可
  • libgit2等のプログラム的git操作と推測されるが、公式な説明を求む

Hackerたちの意見

よく分からないんだけど、権限があればこれを防げるんじゃない?ユーザーが --dangerously-skip-permissions で実行してるから、予測できない動作が起こるのは仕方ないよね。権限とルールセットを使って実行すべきだと思う。

ルールと権限はもはやプログラムのフラグじゃなくて、エージェントが「従う」ためのプレーンテキストになってる。

権限がこれを防げるかどうかは誰にも分からないよね。Anthropicの権限に関するドキュメント(https://code.claude.com/docs/en/permissions)には、権限がどう適用されるかは書いてないし、「権限がサンドボックスとどう相互作用するか」という部分を少し厳しく読むと、実際にはあまり適用されていなくて、プロンプトインジェクションで回避できる可能性があるってことだよね。

シンプルなpretooluseフックを使えば、--dangerously-skip-permissionsでもこれを防げるよ。

この投稿は、特定の人の一回限りの問題を、あたかも広範な問題のように誤解させてる気がする。何か文脈が壊れちゃったのかな?

そうかもしれないけど、影響を考えてみて。もし文脈が0.1%のケースで壊れたら、別の破壊的な動作が出てきちゃうかも。エージェントに1000件のチケットを作成した後に、データが誤って消えちゃうかもしれないよ。

LLMって時々すごくバカなことするよね、それが現実。

これは一回限りの問題じゃないよ。私も何回か経験したことがある。1回はGitHubに強制プッシュしちゃったし、プライベートな個人プロジェクトにはブランチ保護がないからね。例を挙げると、1) claudeはstashする(絶対にやらないようにって明確に指示してるのに)。2) claudeはsedを使って一括置換する(これも絶対にやらないようにって指示してるのに)。sedの置換はめちゃくちゃになって、ファイルをたくさん置き換えちゃう。3) claudeはstashを復元する。たくさんのコンフリクトが見つかる。何も動かない。4) claudeは問題を修正できないと判断して、ハードリセットをかける。これをCLAUDE.mdの一番上に書いておけば、状況は良くなるけど、codexとは違ってclaudeはそれを忠実に守らない。でも、今はかなり良くなったよ。絶対にsedを使って一括置換はしないで。絶対に強制プッシュや破壊的なGit操作は使わないこと: git push --forcegit push --force-with-leasegit reset --hardgit clean -fd、または他の破壊的なGit操作は絶対に禁止。変更を元に戻すにはgit revertを使おう。

つまり、これはスキルの問題だよね。Claude Codeは、モデルの予測不可能性に頼らずに、100%決定論的にこれが起こらないようにするためのツールを提供してくれる。実行したくないGitコマンドを防ぐフックを設定すれば、二度とこんなことは起こらないよ。こういうのを見るたびに、これらの人たちがAIの前にエンジニアだったのか疑問に思う。ソフトウェアエンジニアリングの目的は、何十年もプロセスをできるだけ決定論的で再現可能にすることだったからね。

0.1秒間隔でのプロセス監視では、リセット時にgitプロセスはゼロだった。これが生成されたプロセスを確認する有効な方法だとは思わない。Gitコマンドは速いから、0.1秒の間隔じゃ足りないよ。$PATHのgitを、すべての操作をログに記録してから本物のgitを実行するラッパーに置き換えた方がいい。

これって、Claude Codeが自分の尻尾を追いかけてるだけに見えるな。デバッグできなくて、代わりにユーザーにバグレポートを生成するとか言ってるし。ホストにガードレールがなかったら、ユーザーの入力なしに「エージェント的に」バグレポートを送信するかもしれないし(完全に推測だけど)。E: 逃げ出したボットだね、笑

eBPFはこういうデバッグに使うにはめっちゃいいツールだよ。例えば、bpftraceには、システムで実行されているものを全部見るためのbpftraceのexecsnoopスクリプトがあるしね :-) (bpftraceを使う必要はないけど、簡単な例としてね :-) )

これが一般的かどうかは別として、客観的に面白いから人気が出てきてるよね。みんなそれが可能だって分かるし。

余談だけど、リモートはトランクへのプッシュを拒否するように設定しておくべきだよ。理想的には、ブランチへの強制プッシュもね。

これだ!安全策はLLMの外にあって、決定論的であるべきだよね。今、ローカルシステムでgit reset --hardを拒否できる方法があればいいのに。

本当の問題に集中しよう。HNではタイトルのダブルハイフンがエンダッシュに標準化されてるみたいだね。そう、エンダッシュで、エムダッシュじゃない。

iOSのキーボードオートコンプリート

ダブルハイフン – トリプルハイフン —

そもそも「--」で始まるべきだよね、つまり「--hard」ってこと。

ダブルハイフンのままでいいと思うけど、LaTeXが何十年も前から使ってる前例を考えると、エンダッシュの方がずっと適切だよね(Typstでも続いてるし)。

記事:「最も人気のあるAIコーディングツールの重大な問題」コメント: 「タイトルがAIコーディングだ!!!1」

Appleは自分たちのキーボードのインテリジェンスを良くしたって言う勇気があったんだよね。ほんと冗談だわ。キーボードなんて、クソだね!

enダッシュには二つのハイフン、emダッシュには三つのハイフンを使うよ。

プロのコツ:プロはHNのタイトルをそのままコマンドラインにコピー&ペーストしないんだよね。(それとも…するのかな??うーん、ちょっと考えさせられるな。)

それはLaTeXの規則で、ダブルハイフンがenダッシュ、トリプルハイフンがemダッシュだよ。

SaaS製品に結びついてて、ほとんど雰囲気でコーディングされたバイナリブロブ開発ツールを実行することで、謎のデバッグが難しい問題が起こるなんて、誰が予想しただろうね?

これについてちょっと調べたけど、問題は正確じゃないよ。Claude Code自体にはgit reset --hard origin/mainを実行するコードはないみたい。おそらく、開発者が/loop 10mを実行したか、Claudeに10分ごとに実行してリフレッシュ&リセットするcronタスクを作るように頼んだんだと思う。

参考までに、GitHubへの強制プッシュからはUI[0]やAPI[1]を使って復元できるよ。自分のマシンに強制プッシュした場合はreflog[2]を使えるしね。 [0]: https://stackoverflow.com/a/78872853 [1]: https://stackoverflow.com/a/48110879 [2]: https://stackoverflow.com/a/24236065

これ、Claude Codeが俺のシェル環境に混乱した後に提出してくれたバグレポートに似てるな。著者は何かを実行してるんだと思う(コメントで提案されてる/loopかも)。俺の場合は、再起動したら環境が直ったよ。