- Дата публикации
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 секунд.
Как это работает
Поведение удалось воспроизвести пошагово.
- Пользователь правит отслеживаемый файл
src/lib/api.tsи создаёт неотслеживаемый.canary-test.txt. - Мониторинг раз в 15 секунд показывает: на ближайшей десятой минуте
api.tsоткатывается кorigin/mainбез какого-либо лога или вопроса. Файл.canary-test.txtостаётся нетронутым. 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 или изолированную директорию и не рисковать основным рабочим деревом.