Дата публикации
coding

Claude Code каждые 10 минут делает git reset --hard и может стереть ваш код

Что появилось / что изменилось

У пользователей Claude Code обнаружился крайне неприятный побочный эффект. При работе с репозиторием утилита каждые 10 минут выполняет последовательность git fetch origin и git reset --hard origin/main в текущей директории процесса (process.cwd()).

Ключевые факты:

  • Частота: каждые 600 секунд, строго по таймеру, привязанному к старту сессии.
  • Затронуто: основной рабочий каталог репозитория, с которым запущен claude.
  • Версия: Claude Code 2.1.87 (Homebrew cask, бинарник на Bun) на macOS 15.4 (Darwin 25.3.0, arm64), shell — zsh.
  • Поведение: все незакоммиченные изменения в отслеживаемых файлах исчезают без предупреждения. Неотслеживаемые файлы (untracked) остаются. Git worktree не затрагиваются.
  • Внешний git не запускается — операции идут через встроенную библиотеку (в духе libgit2).

Эту картину подтверждает git reflog: больше 95 записей reset: moving to origin/main с шагом ровно 10 минут в течение примерно 36 часов и четырёх сессий. Смещения по секундам (:08, :36, :41, :09) разные между сессиями, но стабильные внутри каждой, что укладывается в обычный setInterval на 600 секунд.

Как это работает

Поведение удалось воспроизвести пошагово.

  1. Пользователь правит отслеживаемый файл src/lib/api.ts и создаёт неотслеживаемый .canary-test.txt.
  2. Мониторинг раз в 15 секунд показывает: на ближайшей десятой минуте api.ts откатывается к origin/main без какого-либо лога или вопроса. Файл .canary-test.txt остаётся нетронутым.
  3. fswatch на директорию .git/ фиксирует паттерн, характерный для git fetch и git reset --hard:
    • создание и удаление .git/refs/remotes/origin/HEAD.lock;
    • обновление .git/logs/HEAD;
    • создание и удаление .git/refs/heads/main.lock.

Процессный мониторинг с шагом 0,1 секунды не показывает запусков внешнего бинарника git около момента сброса. Замки в .git/ создаёт сам процесс claude.

Через lsof видно, что только один процесс — CLI Claude Code (claude --dangerously-skip-permissions, PID 70111) — использует этот репозиторий как CWD. Другие сессии Claude работают в других директориях.

Разбор бинарника (/opt/homebrew/Caskroom/claude-code/2.1.87/claude) выявил несколько характерных функций:

  • hg1() вызывает операцию вида ["fetch","origin"] через внутренний вызов t_(C8(), _) без явного указания CWD, то есть используется process.cwd().
  • io1() обёртка над git pull, логирующая git pull: cwd=${H} ref=${_??"default"}.
  • Внутренний fileHistory хранит {snapshots: [], trackedFiles: new Set, snapshotSequence: 0}.

Конкретное место с setInterval или таймером в минифицированном коде найти не удалось, но логи и поведение файлов однозначно указывают на периодический fetch+reset в основном дереве. Worktree-репозитории при этом не получают записей reset: moving to origin в собственном reflog и остаются нетронутыми.

Отдельное расследование исключило сторонние причины: git‑хуки (только .sample, без husky и lint-staged), пользовательские хуки Claude (только аудио‑скрипт, без git), обновление маркетплейса плагинов (каталог ~/.claude/plugins/marketplaces/ удалён, поведение не меняется), любые облачные синхронизации (iCloud, Dropbox, Syncthing, Synology, Google Drive не трогают директорию), cron и LaunchAgents, dev‑серверы Vite/SvelteKit, редакторы (nvim в другом репо, без format-on-save), Time Machine и внешние file watchers.

Что это значит для вас

Если вы используете Claude Code CLI 2.1.87 на macOS и запускаете его внутри рабочего git‑репозитория, есть риск регулярно терять незакоммиченные изменения. За двухчасовую сессию можно трижды лишиться правок в отслеживаемых файлах и долго искать, кто их откатывает.

Практические выводы:

  • Не храните важные незакоммиченные изменения в основном рабочем дереве, если рядом крутится Claude Code.
  • Используйте git worktree для директорий, где запускаете claude. Тесты показывают, что worktree не получает автоматических reset.
  • Коммитьте чаще. Всё, что есть в коммите, переживает сброс, потому что reset --hard origin/main просто пересаживает HEAD на тот же коммит, если ветка и так синхронизирована.
  • Не полагайтесь на локальные несохранённые ветки как на черновики, пока работает этот релиз Claude Code. Лучше создайте отдельную ветку и делайте реальные коммиты.

Если вы запускаете CLI с флагом --dangerously-skip-permissions, будьте особенно осторожны: именно такой процесс участвовал в расследовании, и он имел полный доступ к репозиторию без дополнительных диалогов безопасности.

Пока команда Claude Code не объяснила, какой внутренний механизм отвечает за периодический git fetch origin + git reset --hard origin/main против process.cwd() и зачем он включён по умолчанию. Из внешних наблюдений видно только таймер на 600 секунд и программную работу с .git без внешнего git.

Место на рынке

История показывает обратную сторону глубоких интеграций ИИ‑инструментов с git. Большинство CLI‑ассистентов — от расширений для VS Code до терминальных помощников — ограничиваются чтением состояния репозитория или явным запуском git по запросу пользователя.

В случае Claude Code часть логики живёт внутри самого бинарника: он общается с репозиторием через библиотеку наподобие libgit2, создает lock‑файлы в .git/ и не оставляет следов в списке процессов git. Из-за этого разработчик может долго не замечать источник проблем: пока все изменения закоммичены, периодический reset безвреден и никак себя не проявляет.

Для ИИ‑инструментов следующего поколения это важный сигнал: любая автоматизация вокруг git должна быть максимально прозрачной, с явным включением и логами. Пока же пользователям Claude Code проще действовать консервативно: вынести ассистента в отдельный worktree или изолированную директорию и не рисковать основным рабочим деревом.


Читайте также

Claude Code каждые 10 минут делает git reset --hard и может стереть ваш код — VogueTech | VogueTech