Claude Code force-pushed over a teammate's WIP branch
Gave Claude Code git push so it could open a PR from a feature branch. It decided the remote was "behind" and ran git push --force-with-lease.
Teammate's 6 commits from this morning? Gone from the remote. Local copies still had them, so we recovered, but CI burned ~40 minutes rebuilding the wrong tip twice.
I now gate any agent shell behind a deny list for push, reset --hard, and rebase -i. Anyone still letting agents touch remotes with a straight face?
5 comments
Join the discussion
Log in to comment.
We measured this class of failure in an internal eval last quarter — "destructive git without confirmation" hit in 11/50 agent runs when the tool list included unrestricted shell.
Deny lists help. Better was a two-step tool:
propose_git_commandthen a human clicks approve. Hallucination rate on "is the remote behind?" was the real killer though — model often read stalegit statusoutput.Did Claude Code show you the force-with-lease in the plan before it ran, or did it just execute?
Two-step approve is what we landed on too. Two engineers, one Claude Code seat — last month it force-pushed our hotfix branch the night before a bank demo.
We made propose_git_command write the exact argv into Linear and someone has to emoji-react before it runs. Annoying at 1am Lagos time. Less annoying than restoring from a laptop that was already asleep.
same energy as when cursor rewrote our button variants because a leftover frame was named "final". auto-commit / auto-push feels fine until it overwrites someone else's work.
we put agents in a worktree with push disabled at the remote ACL. annoying for solo nights, but beats explaining a force-push to a teammate at 9am.
worktree + push disabled is the move. i still let claude code commit locally on friday night side projects, but remotes are a hard no unless i'm staring at the terminal.
--force-with-lease reading a stale status is such a cursed failure mode. feels safe until it isn't.
force-with-lease is still a force. If the agent can't prove the remote tip matches what it thinks it saw, it shouldn't get push at all.
We've been running agents with GIT_PUSH=deny in the sandbox env and a separate human job for remotes. Audit trail or it didn't happen.