AI agent commits: keep a git history you can actually revert
23:47. Checkout is throwing 500s for about one user in twenty, and you already know which afternoon did it. You open the log:
a3f1c9e Implement user profile improvements
One commit. Thirty-one files. Inside it: the profile work you asked for, a currency helper the agent tidied on the way past, a dependency bump it decided was related, and the one change you actually need to undo.
git revert a3f1c9e takes out the whole afternoon, working parts
included. git bisect has nothing to bisect: your last three commits
are three afternoons. So you do it the slow way, reading thirty-one
files at midnight, hunting for the line that matters.
The code was fine. The history was also a deliverable, and nobody wrote it.
Why AI coding agents produce one giant commit
An agent commits when the conversation ends, not when a change becomes independently revertable. Its unit of work is your prompt. Yours is the thing you might one day take back out. Those two rarely line up, and the longer the session runs, the further apart they drift.
The message has the same problem. It gets written from the plan, not from the diff, so it inherits the optimism of the prompt instead of reporting what landed. Researchers who read 23,247 agent-authored pull requests found the most common inconsistency was descriptions claiming changes that were never implemented. Only 1.7% of the pull requests scored high on that, but those were accepted 28.3% of the time against 80.0% for the rest, and took 3.5 times longer to merge. A description of work that does not exist is worse than no description, because you trust it once.
One commit per thing you might undo
The rule that fixes most of this is short: a commit is a unit of revert, not a unit of work.
Apply it with one question. If this turns out to be wrong at midnight, is there exactly one commit to remove, and does the tree still work after it is gone? If not, the change wants splitting.
That is a policy an agent can follow, once you write it into the brief or your agent instructions file instead of hoping for it:
Commit each self-contained change as you finish it, before starting the next one. Never mix a refactor with a behavior change. Never bundle formatting or import sweeps into a feature commit. If the task makes you touch a file outside its scope, stop and tell me.
Notice this is the same question as how big a task you hand over. A task that produces one revertable change produces one clean commit almost by accident. A task described as "improve the profile page" produces the blob above, every time.
Splitting a mess afterwards works (git add -p, or asking the agent to
rebase it into pieces), it just costs a session to rebuild intent that
was free to record live.
The agent knows what changed. You know why.
Give agents credit: they read the diff before writing about it, so their subject lines beat what a tired human types at 18:30. Simon Willison's notes on using git with coding agents go further: ask for commits to be reorganized and the model will do it.
What it cannot know is why. The constraint you gave verbally, the approach you rejected in the first ten minutes, the customer report behind the whole thing: none of that is in the diff, so none of it reaches the repo unless you put it there.
So split the job. Subject line from the diff, body from the brief. The body carries three things worth having at midnight: why this happened now, what was considered and dropped, and what to check first if it breaks. One line each is plenty.
Then hold one hard rule: the message may never claim more than the
diff does. Reading the subject next to git show --stat costs a
second and is the cheapest verification step in the whole workflow. To
enforce it rather than remember it, that is the job of
a hook: block the commit command when it
carries -A or -a, and let the pathspec form through.
Commit hygiene when several agents share one repo
Run more than one session in a tree and git add -A stops being sloppy
and starts being dangerous. It sweeps up whatever the other agent has
half-written, so your commit carries work you have never read, filed
under a task it has nothing to do with. Revert it later and someone
else's afternoon goes with it.
Three habits keep parallel work honest. Branch per task, ideally with a worktree per agent so the trees cannot mix in the first place. Stage by pathspec, naming the files the task owns instead of everything that happens to be dirty. And one merge per task, so the branch stays the unit you review, in the way reviewing agent output already assumes.
Where commit discipline goes wrong
The obvious failure is the opposite of the blob: fourteen commits called
"wip", each one a keystroke of progress. Bisect needs every commit to
build, and a checkpoint dropped mid-refactor does not, so that history
makes git bisect answer "skip" until you give up on it. Checkpoint
freely while working, squash before merging.
The expensive failure is rewriting. Agents are fluent with --amend,
interactive rebase and force-push, and fluent plus unsupervised is how a
commit you already reviewed becomes a different one, or how an hour of
work stops existing. Rewriting shared history should be human-only,
denied at the permission layer
rather than discouraged in prose.
Then the boring one: git add -A commits .env, build output and a
40MB fixture directory. Rotating the leaked key is the cheap part.
The cost runs both ways, though. Commit discipline spends tokens and adds a beat between steps, and for a throwaway spike it is ceremony. If nothing in the session will ever need reverting, skip all of it.
A desk where the card is the commit boundary
That is the part SanuDesk was built around. It is a desktop app for running Claude Code, Codex and Gemini sessions side by side: they tile into one grid, so you can see which agent is mid-commit instead of finding out afterwards.
Next to the grid sits a Kanban board, and that is where the boundary
gets set. You write a card scoped to one change, deploy it to a fresh
session with a click, and the scope on the card becomes the scope of the
commit. When the agent stops, the card lands in a review lane with a
what-changed note you read straight against git log. Recurring checks
become a Loop: a weekly pass listing every commit from the last seven
days that touched more than fifteen files, journaled so the trend stays
visible. It drives the model subscriptions you already pay for, and the
grid and board are in the free plan (see pricing).
Run one command tonight
Point this at the last week of agent work:
git log --oneline --stat --since='7 days ago'
Count the files per commit, take the largest one, and ask the only question that matters: could you revert exactly that change tomorrow without taking anything else with it? If not, add the three commit clauses above to your agent instructions file before the next session starts. It is a ten-second check that decides how expensive your next incident is.
Download SanuDesk free to keep one card, one session and one commit pointing at the same change, or see how the grid, the board and Loops fit together on the features page.