If you use an assistant to help with coding, you’ve probably felt this tension:
- You want speed (generate code, refactor, write tests, update docs).
- You still need safety (don’t break main, don’t ship surprising changes).
The simplest workflow I’ve found that keeps both is what I call Branch-per-Ask:
Every meaningful request to your assistant happens on a fresh Git branch, with a clear goal and a tiny merge surface.
It’s not fancy. It’s just a small discipline that turns “messy chat-driven changes” into something you can review, test, and revert like normal software work.
Below is the playbook I use (with concrete commands, prompts, and a couple of habits that make it stick).
Why Branch-per-Ask works
When you ask for help in-place (on main or a long-running branch), three things tend to happen:
- Changes accumulate without a boundary. You lose track of what the assistant touched “for this thing” vs “for that thing.”
- Review becomes vague. A diff that mixes refactors + fixes + formatting is hard to approve confidently.
- Rollback is painful. If you need to undo one request, you often undo five.
Branch-per-Ask adds a hard boundary around a single intent. That boundary buys you:
- a clean diff
- a testable unit of work
- a natural “stop” point
The core rule
One branch = one request = one outcome.
Examples of good “one outcome” asks:
- “Add a CLI flag
--dry-runand update docs.” - “Refactor this module to remove circular dependency, no behavior change.”
- “Write unit tests for
parseInvoice()covering these 6 cases.”
Examples of bad asks (too broad):
- “Clean up the codebase.”
- “Improve performance.”
- “Modernize everything.”
If the ask isn’t specific, the branch won’t be either.
Step-by-step workflow (copy/paste)
1) Start from a known-good base
git switch main
git pull
If you’re working off a release branch or a feature branch, start from that instead — the point is: begin from something stable.
2) Create a branch that encodes intent
git switch -c ai/add-dry-run-flag
My naming convention:
- prefix:
ai/(so it’s obvious this was assistant-assisted work) - verb-first:
add-,fix-,refactor-,test-,doc- - small scope
This is not about credit or blame. It’s about fast filtering later when you’re scanning branches.
3) Write the ask like a tiny spec
Before you paste code, write the constraints.
Here’s a template that consistently produces reviewable changes:
Goal:
- Add a --dry-run flag to the "sync" command.
Constraints:
- No behavior changes when the flag is not provided.
- When --dry-run is set, print what would happen, but do not write.
- Update README usage examples.
- Keep changes minimal; avoid unrelated refactors.
Deliverables:
- Patch/diff.
- A short summary of what changed and why.
- Tests (unit or integration) proving dry-run does not write.
Two subtle wins here:
- You’re defining what not to change.
- You’re asking for a patch + summary, which makes review easier.
4) Keep the branch “small by default”
When the assistant proposes a plan, keep the first iteration narrow.
A rule of thumb:
- If the diff is > 250 lines, ask for a smaller slice.
- If the assistant touches more than 3–5 files, ask why.
You can always do another Branch-per-Ask after merging.
5) Commit with a message that matches the intent
git status
git add -A
git commit -m "Add --dry-run flag to sync"
This matters because it makes git log tell the story later.
6) Test like you mean it
Run the smallest “confidence suite” for your project. Examples:
npm test
npm run lint
Or:
pytest
ruff check .
If the assistant added code but no tests, don’t accept it by default. Instead, do a second ask on the same branch:
- “Now add tests for these specific cases. Do not change implementation unless required to test.”
7) Review the diff as if it was a PR from a teammate
Two commands I use constantly:
git diff main...HEAD
…and:
git show --stat
What I’m looking for:
- does the diff match the stated goal?
- any new dependencies?
- any formatting-only churn?
- are errors handled consistently?
If anything feels off, don’t fix it ad-hoc on the branch. Instead, issue a new, precise ask:
- “In this diff, file X introduces Y. Please remove that; keep behavior unchanged.”
This keeps the branch coherent.
8) Merge and delete
If you use PRs, open one and merge normally. If you merge locally:
git switch main
git merge --no-ff ai/add-dry-run-flag
git push
git branch -d ai/add-dry-run-flag
The delete step is part of the pattern. It keeps your repo from becoming a graveyard of half-finished assistant experiments.
The “two-branch” upgrade: explore vs ship
Sometimes you do want exploration (a big refactor, alternative architecture, performance experiments).
In that case, split the work:
-
ai/explore-…— messy is allowed, prototypes are allowed -
ai/ship-…— only contains the minimal, reviewable final change
Workflow:
- explore freely
- once you know what you want, create a clean ship branch from
main - cherry-pick the relevant commits
git switch -c ai/ship-http-timeout-fix main
git cherry-pick <commit>
You get the benefits of experimentation without shipping the mess.
A tiny PR checklist (I reuse this constantly)
Paste this into your PR description:
### Intent
- (one sentence)
### Scope
- [ ] Only changes required for intent
- [ ] No drive-by refactors
### Safety
- [ ] Tests added/updated
- [ ] Lint/format passes
- [ ] Error handling consistent
### Review notes
- Files touched: __
- Risky areas: __
The checklist does one important thing: it makes you explicitly confirm that the assistant didn’t “helpfully” expand the scope.
Common failure modes (and what to do)
1) The assistant rewrites everything
Fix: restate constraints and ask for a smaller patch.
“Keep changes limited to files A and B. Do not reformat unrelated code. Provide a minimal diff.”
2) The assistant adds dependencies casually
Fix: make “no new deps” a default constraint unless you really want them.
3) You can’t tell what changed
Fix: require a patch letter with the diff:
- what changed
- why it changed
- how to validate
- what to watch out for
(If you’re reading this thinking “that’s just a good PR description”… exactly.)
The payoff
Branch-per-Ask isn’t about ceremony. It’s about keeping your codebase legible when you’re moving fast.
Once you adopt it, you’ll notice a shift:
- you ask smaller, clearer questions
- you review diffs more confidently
- you ship more often with fewer surprises
Try it for your next 5 assistant-assisted changes. If nothing else, your git log will thank you.
Top comments (0)