Git from First PrinciplesPost 11 of 16 · 16 of 16 written
- How to use this guide
- 01Why version control exists
- 02Git's data model: a content-addressed object database
- 03References: branches, HEAD and tags are pointers
- 04The three areas: working tree, index, repository
- 05Daily commands, mapped onto the model
- 06Branching and integration: merge, rebase, cherry-pick
- 07Undoing things safely
- 08Remotes and collaboration
- 09Workflows and conventions
- 10Git for AI and ML work
- 11Git with AI coding agents
- 12Power tools
- 13Under the hood: build a commit by hand
- 14Debugging mindset and recovery playbook
- 15Practice path, fluency checklist and glossary
- 16Sources
11. Git with AI coding agents
When an agent writes the code, Git becomes your control system. Commits are checkpoints you can return to, diffs are where you review, branches and worktrees are sandboxes, and hooks and CI are guardrails that apply no matter who typed the code.
The principle: the agent proposes changes; you own the history. Agents are fast, sometimes wrong, and happy to touch twenty files. Git turns that into a process you can review and reverse.
The checkpoint loop
- Start clean, on a branch.
git statusshows nothing;git switch -c feat/eval-harness. - Give the agent one well-scoped task.
- Check scope first.
git status --shortandgit diff --stat: did it touch only what the task needed? - Review the content. Read
git diff, or stage hunk by hunk withgit add -pso approval is explicit. - Run the tests.
- Commit what you approve with a message that states what and why. Discard the rest with
git restore ., andgit clean -nthengit clean -fdfor stray new files. - Repeat. If a step goes badly,
git reset --hard HEADtakes you back to the last checkpoint in one command.
Small commits make rollbacks cheap. Never let an agent work for an hour on a dirty tree with no checkpoint to return to.
Commands for reviewing agent output
git status --short # includes new scratch files agents like to create
git diff --stat # which files, how many lines
git diff -w # ignore whitespace-only noise
git diff --word-diff # word-level changes inside lines
git diff main...HEAD -- tests/ # everything this branch changed in the tests
git log -p -1 # review the last commit in fullThe three-dot form main...HEAD compares against the merge base, so it shows only your branch’s changes, not what changed on main meanwhile.
What to look for in an AI diff
- Scope creep: unrelated refactors or reformatting mixed into the change.
- Weakened tests: deleted tests, new
skipmarkers, loosened assertions. “All tests pass” means little if the tests changed. - New dependencies: read the lockfile and requirements diff.
- Hard-coded values: secrets, absolute paths, magic numbers.
- Changed defaults: a config default flipped silently can change every run.
- Accidental files: caches, outputs, notebooks with outputs,
.env.
Worktrees for parallel agents
One working tree holds one checkout. Two agents in the same folder overwrite each other, and switching branches under a running agent breaks it. git worktree gives one repository several working trees. They share the object database; each has its own HEAD, index and files.
git worktree add ../proj-auth -b feat/auth
git worktree add ../proj-eval -b feat/eval-harness
git worktree list
# run one agent in each folder, review and merge as usual
git worktree remove ../proj-authTwo rules. A branch can be checked out in only one worktree at a time. And untracked files are not shared, so each worktree needs its own virtual environment and installed dependencies.
Hooks: local guardrails
Hooks are scripts Git runs at fixed moments: pre-commit, commit-msg, pre-push and others, stored in .git/hooks. That folder is not versioned, so teams use the pre-commit framework: a committed .pre-commit-config.yaml, activated on each machine with pre-commit install.
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: <release tag>
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/gitleaks/gitleaks
rev: <release tag>
hooks:
- id: gitleaks
- repo: https://github.com/kynan/nbstripout
rev: <release tag>
hooks:
- id: nbstripoutRun pre-commit autoupdate to fill in current release tags. Now every commit, yours or an agent’s, is linted, formatted, scanned for secrets and stripped of notebook outputs.
CI: the guardrail nobody can skip
Hooks run locally and can be bypassed with --no-verify, by you or by an agent. So CI must repeat the checks on the server for every push and pull request. Branch protection then makes passing CI a condition for merging into main.
Rules for agents that run Git themselves
Many agents run Git commands directly. Allow the read-only and local ones freely: status, diff, log, add, commit on a feature branch. Require your approval for push, any force-push, reset --hard, clean, and rebasing or rewriting anything shared. Protect main on the host so even a mistaken push cannot land there.
Repository instruction files for agents, such as AGENTS.md or CLAUDE.md, are committed like code. Put your Git conventions there: branch names, commit format, what must never be committed.
When something broke and nobody knows when
Agent-heavy projects produce many commits quickly, and regressions slip in. git bisect binary-searches history for the commit that introduced a failure, and git bisect run pytest tests/test_x.py automates it (Part 12). Small atomic commits are what make the answer precise.
Check yourself
- An agent reports “all tests pass”. Which command checks whether it edited the tests?
- Why can’t two agents share one working tree, and what does a worktree share versus keep separate?
- Why must CI repeat checks that your pre-commit hooks already run?