A Coding Agent on a Branch vs on Main: The Habit That Makes a Bad Edit Recoverable
Chris Vale
September 30, 2026
I lost most of a Saturday evening to a refactor I did not write. I had spent two hours on my own changes to a small home-inventory app I keep for our household: a barcode lookup, a new column for expiry dates, a handful of fixes. None of it was committed. I was on main, as I usually am on personal projects, because there is nobody else to coordinate with and branches felt like ceremony.
Then I asked a coding agent to “clean up the storage layer,” meaning the module that talks to SQLite. It did, enthusiastically. It renamed functions, split one file into three, changed the signature of the function my new expiry code called, and updated all the callers, including the ones I had just written. Then I ran the app and the barcode lookup broke in a way I did not understand.
I wanted to throw the agent’s changes away. I could not. git checkout . would have thrown away my two hours along with its twenty minutes. My changes and its changes were interleaved in the same files, sometimes on adjacent lines. There was no commit between “my work” and “its work.” There was just a working tree containing both.
I spent the next hour and a half with git diff and git add -p, trying to remember which hunks were mine. I got most of them. I think. Since then, I have one habit I do not skip, and it has made every bad agent edit since then a thirty-second fix.
The habit: a clean line before the agent starts
Before an agent touches a repository, there should be a commit that represents “everything I did,” and nothing uncommitted. The agent’s work then happens on top of that line, ideally on its own branch. If the result is bad, you return to the line. If it is good, you keep it. Either way, your work and its work never share the same unsaved state.
That is the whole habit. Everything else in this piece is about making it cheap enough that you actually do it every time, including on a Saturday evening on a hobby project.
Why “on main” is really “on a dirty tree”
The branch name was not really the problem that evening. Working on main in a personal repository is fine. The problem was that my uncommitted work and the agent’s work landed in the same place with no boundary between them.
When you write code yourself, a dirty working tree is normal. You know what you changed because you changed it. An agent breaks that assumption. It can edit many files quickly, including files you have open and half-finished. Once its edits are mixed with yours, git has no idea which lines came from whom. Neither, after a while, do you.
The most common version of this is subtler than mine. You have a small uncommitted change, a debug print or a config tweak, and you ask the agent for something unrelated. It edits the same file. Now your debug print is tangled into its diff, and either you commit it by accident or you remove it and lose track of what was yours.

What I do now, step by step
1. Commit or stash my own work first. Before starting an agent task, git status should be clean. If I have work in progress, I commit it with a message like “wip: expiry column,” even if it is half-done. A WIP commit is cheap, and I can squash it later. If the work is something I do not want in history at all, git stash works too, though I find stashes easy to forget.
2. Create a branch for the agent’s task. git switch -c agent/storage-cleanup. Three seconds. On a personal project, the branch is not for collaboration. It is a named place to put the experiment so that main stays at a known-good point.
3. Let the agent work. Whatever it does happens on that branch, on top of my clean commit.
4. Review with a clean diff. git diff main shows only the agent’s changes. Nothing of mine is mixed in. This alone makes review dramatically easier, because every line in the diff is something I did not write and need to check.
5. Keep, fix, or discard. If it is good, merge it into main. If it needs fixing, fix it on the branch. If it is bad, git switch main and git branch -D agent/storage-cleanup. Gone, with my own work untouched.
Had I done this that Saturday, the refactor’s breakage would have cost me the time it took to type two commands.
Checkpoints inside a long task
For longer agent tasks, a single branch is not enough granularity. If an agent works through six steps and step five goes wrong, throwing away the whole branch also throws away steps one to four.
So for multi-step work I commit at each step that works. Sometimes I ask the agent to do it: “after each step passes the tests, commit with a short message.” Sometimes I do it myself between prompts. Either way, the branch ends up with a sequence of small commits, and a bad step can be undone with git reset --hard HEAD~1 without losing the good ones. I squash when merging if I do not want the noise in main.
This also makes the agent’s work far easier to review. A branch with six focused commits can be read one commit at a time. One enormous diff cannot.

Tool checkpoints are not git
Several coding tools offer their own undo: a “restore checkpoint” button that rolls back the agent’s edits to an earlier point in the conversation. These are useful, and I use them for quick reversals. But I stopped treating them as a substitute for git after one surprised me.
The agent had run a code generator as part of its task, which rewrote a dozen files, and then run the project’s formatter, which touched a few more. When I restored the checkpoint, the tool reverted the files it had edited directly. It did not revert the files changed by the commands it ran, because it had not tracked those as its own edits. I ended up with a half-reverted tree: original source files, regenerated output from the new version.
Git does not care how a file changed. git diff shows everything that differs from the last commit, whether the agent typed it, a generator wrote it, or a formatter reflowed it. That is exactly the property you want when you are trying to get back to a known state.
Worktrees for running an agent while you keep working
The last piece of the habit is for when I want to keep working myself while an agent handles something else. Switching branches in one working directory means I have to stop, and the agent and I would be fighting over the same files.
git worktree add ../inventory-agent agent/barcode-cache creates a second working directory on its own branch, sharing the same repository. I point the agent at that directory and continue in mine. Our changes cannot collide, because they are in different folders on different branches. When the agent is done, I review its branch like any other and merge or delete it, then remove the worktree.
On a small project, this felt like overkill at first. Now it is how I run anything that will take the agent more than a few minutes. It costs one command and saves me from ever again untangling interleaved edits by memory.
What about teams?
On a shared repository, most of this is already the norm: nobody commits directly to main, everyone works on branches, pull requests gate merges. What teams sometimes miss is the first step, the clean line before the agent starts. It is common to see a developer with a dirty working tree on a feature branch ask an agent for help, and then commit the whole mix as one change. The branch does not help if the mess is inside it.
The rule scales down and up the same way: your work committed, the agent’s work on top, a clear boundary between them.
Recovering when you forgot
I still occasionally forget. When I realise an agent has edited files on top of my uncommitted work, I stop immediately and do not ask it to “undo that.” An agent undoing its own edits in a tangled tree tends to undo some of mine too. Instead, I run git diff and save the output to a file so nothing is lost, then use git add -p to stage the hunks I recognise as mine, commit them, and look at what remains. It is tedious, but it is safe, and the saved diff means I can always reconstruct if I get it wrong.
And git reflog is worth knowing about. If you committed at any point before things went wrong, even a commit you later reset away, the reflog remembers it for a while. It has rescued me once.
Small habit, large payoff
The storage layer refactor, when I redid it the next week properly on a branch, turned out to be decent apart from the signature change that broke the barcode lookup. I kept four of its five changes and dropped the fifth. That kind of partial acceptance is only easy when the agent’s work is isolated.
The habit costs me about ten seconds per task: git status, commit if needed, git switch -c. It has turned every bad agent edit since that Saturday into something I can throw away without a second thought. It is the cheapest insurance I have in my whole setup.