Git Discipline for Agents
When a human developer works in git, they use branches, commit deliberately, and avoid force-pushing to main. When an agent works in git, the same rules apply — except the agent is faster, less cautious by default, and doesn’t feel bad about making a mess. Without explicit discipline, agents will commit directly to main, write unclear commit messages, and in multi-agent setups, trample each other’s work.
This article covers the git rules that keep agent work reviewable, recoverable, and safe.
Always work on a branch
Section titled “Always work on a branch”The default branch (main or master) should reflect what’s actually deployed and working. Agent work belongs on a feature branch until it’s been reviewed and confirmed.
The rule is simple: before making any edit, the agent should be on a branch that isn’t main. In practice, every task starts with:
git checkout -b feat/short-description-of-taskOr, if there’s an existing feature branch for this work:
git checkout feat/existing-featureWhy this matters: if the agent does something wrong on a branch, you discard the branch. If it does something wrong on main, you’re untangling production state under pressure.
Commit conventions
Section titled “Commit conventions”Agent commits should be readable by humans — you’ll be reviewing them, and you’ll want to understand what changed and why from the message alone. A commit message like “fix stuff” from an agent that ran for 3 hours and touched 40 files is useless.
A simple convention that works: one sentence describing what changed and why. The “why” is the part most agents skip:
fix: billing_address bug in order_webhook — was using billing addressinstead of shipping, causing Printful 'line1 blank' errors on real ordersThe format that this system uses: a type prefix (fix:, feat:, refactor:, test:, chore:), a short summary, optionally a body sentence explaining the root cause or decision.
Beyond the message: one logical change per commit. An agent that runs pytest, fixes 3 bugs, adds 2 tests, and updates a README in one commit is hard to review and hard to revert partially. Prompt the agent to commit the fix, then the tests, then the docs update — separately.
Don’t force-push, don’t drop commits
Section titled “Don’t force-push, don’t drop commits”Force push rewrites history. If any other session, agent, or human has branched off that history, they’re now in a confusing diverged state. The rule: git push --force is banned except for explicit rebasing workflows that the operator explicitly initiates.
This belongs in settings.json as a deny rule:
"permissions": { "deny": ["Bash(git push --force*)"]}The parallel-agent trampling problem
Section titled “The parallel-agent trampling problem”A more advanced issue — but worth knowing early so you understand why the discipline exists — is what happens when multiple agents work in the same git checkout simultaneously.
Two agents, same repo, same branch: Agent A runs git checkout feat/my-feature to start work. Agent B, handling a different task in the same session, also needs to switch branches. It runs git checkout feat/other-feature. Now Agent A is suddenly working in a different branch from the one it started in. Its subsequent edits land in the wrong branch.
This actually happened during the development of the system described in Tier 3. Two incidents in May and June 2026 cost roughly 15 minutes of recovery each time — cherry-picks and reflog archaeology to retrieve commits that had landed in the wrong branch.
The solution is worktree isolation: each agent gets its own git working tree, so git checkout in one agent’s worktree doesn’t affect any other. This is a Tier 2 topic (covered in detail at Worktree Isolation), but the motivation starts here: parallel agents + a shared git working tree = a race condition waiting to happen.
A minimal git workflow for agent work
Section titled “A minimal git workflow for agent work”For a single agent on a single task:
# Start: branch from maingit checkout main && git pull && git checkout -b feat/task-name
# Work: agent edits files
# Check: run tests before committingpytest -q # or whatever the test command is
# Commit: staged + clear messagegit add specific-files.pygit commit -m "fix: short description — why it was wrong, what changed"
# Push: feature branch only, no forcegit push -u origin feat/task-name
# After review: merge or PR — not the agent's job to merge to mainThe last line is important: merging to main is a deliberate, human-authorized step. The agent ships a feature branch with passing tests; a human (or a CI pipeline) decides it’s ready to merge.
Next: Logging & Instrumentation — why instrumenting what you build is not optional, and how the clawd-log.sh + master CHANGELOG pattern makes a multi-project system legible.