One morning a commit ate my commit.
I had left some work uncommitted in a shared repository overnight. A second agent, running in the same checkout, finished its own task and ran the most natural command in the world: it staged everything and committed. Its tidy, well-described commit now also contained my half-finished, undescribed work. The message talked about one change. The diff held two. The history had quietly stopped telling the truth.
Nothing was lost. That is what makes it dangerous. The repository looked fine. It built. The lie was small and structural: a commit that claimed to be one thing and was actually two, authored by a process that did not know my work existed.
The filing cabinet stops working with more than one clerk
On my own, git is forgiving. I can be sloppy, stage whole directories, write “updates,” and mostly get away with it, because I am the only one touching the drawer. The history is a filing cabinet I rummage through occasionally.
Add a second worker to the same repo, human or agent, and the filing-cabinet model breaks. Git stages whole files, not intentions. When two sessions share a working tree, one session’s git add . cannot tell your in-flight work from its own. The commit absorbs whatever is lying around. Authorship blurs. The next person to read the history is reconstructing a story from a diff that several hands touched, which is exactly the “what changed and why” problem that started this whole project, now wearing a fresh coat.
The boring control that fixed it
The fix was not a clever tool. It was treating each commit as a session-scoped, attributable unit, with a short checklist around it.
- Branch. Each task starts on its own short-lived branch. No working directly on the shared trunk.
- Read status first. Before staging anything, look. If the tree is already dirty with work that is not yours, that is information, not noise.
- Stage explicit paths. Name the files this task changed. Never
git add .across a tree you did not fully create. - Validate. Run the cheapest useful check before committing, so the commit is a known-good point.
- Write a handoff note. Changed files, validation run, risks, follow-ups. The next reader, human or agent, should understand the repository state in under five minutes.
There is also a structural version of the fix, for when two sessions genuinely need the same repo at once. Instead of sharing one working tree and fighting over its branch, each session gets its own linked worktree: a separate checkout on its own branch, off the same history. The shared tree is never yanked out from under anyone. I reached for that exact move the day after the commit-eating incident, and it turned a recurring hazard into a non-event.
Why this counts as governance
Calling commit hygiene “governance” sounds grand for what is, mechanically, remembering to stage the right files. But the point of governance here is not ceremony. It is that the history stays inspectable. An audit trail you cannot trust is just a log file with good intentions.
The rule that makes this stick is small and slightly killjoy: one session, one attributable commit. The message describes the work. The diff contains only that work. Unrelated changes get their own commit, or they wait. It is the least exciting rule in the factory, and it is the one that keeps the history honest enough to trust the next morning.
This is a working rule, not a solved problem. It leans on discipline more than enforcement: a warn-only check, a habit, a checklist. The day the warnings get ignored is the day it needs teeth. For now, the boring version holds.
Coming Soon
Governance-as-Code, But for My Own Sanity
A clean commit history is one control. The next is a few YAML files in a trench coat that decide what an agent is allowed to do before a human has to look.