Prevent Claude Code git reset --hard Disasters

git reset --hard destroys all uncommitted changes instantly. No confirmation, no recycle bin, no undo. Claude Code runs it when it thinks "starting fresh" is the fastest path forward.

What Gets Destroyed

When Claude runs git reset --hard:

Combined with git clean -fd (which Claude also runs), even untracked files are deleted.

When This Happens

Claude "cleans up" after a failed approach

Claude tries an implementation, hits errors, and decides to start over. It runs git reset --hard HEAD to "clean the slate" — wiping your uncommitted work along with its own.

Claude resolves merge conflicts by force

During a merge conflict, Claude runs git reset --hard origin/main instead of resolving conflicts. Your local changes are overwritten with the remote state.

Autonomous session at 3am

While you sleep, Claude encounters a problem and runs git reset --hard && git clean -fd. You wake up to find your working directory matches the last commit — everything else is gone.

Why CLAUDE.md Can't Prevent This

A CLAUDE.md rule saying "never run git reset --hard" is a suggestion. When context fills up or Claude determines the reset is "necessary," it can and will ignore the rule. Hooks operate at the process level — the model cannot bypass them.

The Fix: destructive-guard Hook

destructive-guard.sh blocks dangerous git commands:

#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

# Block git reset --hard
if echo "$COMMAND" | grep -qE 'git\s+reset\s+--hard'; then
  echo "BLOCKED: git reset --hard destroys uncommitted work" >&2
  exit 2
fi

# Block git clean -fd
if echo "$COMMAND" | grep -qE 'git\s+clean\s+-[a-zA-Z]*f'; then
  echo "BLOCKED: git clean -f deletes untracked files permanently" >&2
  exit 2
fi

exit 0

This hook runs before every Bash command. Exit code 2 blocks the command before it executes.

What destructive-guard Blocks

CommandResult
git reset --hardBLOCKED
git reset --hard HEAD~3BLOCKED
git clean -fdBLOCKED
git reset --soft HEAD~1ALLOWED
git checkout -- file.jsALLOWED (use uncommitted-discard-guard to block)

Also Block: git checkout -- and git restore

git checkout -- <files> and git restore . silently discard working tree changes — no confirmation, no undo. #37888 reported 30+ files of manual edits destroyed this way.

npx cc-safe-setup --install-example uncommitted-discard-guard

Blocks git checkout --, git checkout ., git restore (except --staged), and git stash drop.

Install All 8 Safety Hooks in 10 Seconds

npx cc-safe-setup

Blocks git reset --hard, rm -rf, force-push to main, secret leaks, and more. 9,200+ tests 655 examples

GitHub · npm · Getting Started Guide

Check Your Safety Score

npx cc-health-check

Free 20-point diagnostic. Score below 80 means your Claude Code setup has gaps.

cc-safe-setup is open source, zero dependencies, and installs nothing globally. View source on GitHub.

New: Hook if field — reduce overhead (v2.1.85)

Learn more: Production Guide · All Tools