Lesson 6 of 9 · about 15 minutes

Claude Code on a branch

Give the agent a sandbox, read what it built, and only then let it near main.

You will run one complete Claude Code task on an agent branch: brief it, review its commits, have it open a pull request that CI checks, and know how to throw the whole thing away if it goes wrong.

The loop

You already have every piece: branches (lessons 1–3), pull requests (lesson 4), and CI on pull requests (lesson 5). An agent branch puts them in order around Claude Code:

  1. Start from a fresh main. Switch to main and pull, so the agent builds on the latest work.
  2. Create the branch. One task, one branch: git switch -c standardize-columns. You can also ask Claude to create it. Claude Code gets a git status snapshot at session start (current branch, main branch, recent commits), so it knows where it is.4
  3. Brief the agent: explore → plan → implement → commit. Claude Code's best-practices guide recommends exactly this order. The last step is a prompt like "commit with a descriptive message and open a PR."1
  4. Review the branch. Read the commits and the three-dot diff before anyone else does.
  5. Ship as a pull request. Claude opens it with gh pr create.2 CI runs on it automatically, because your workflow triggers on pull requests to main.
  6. Merge or discard. Squash-merge good work and delete the branch. Bad work? Delete the branch, and main never saw it.

Briefing prompts you can copy

The task: add standardize_columns(df) to clean.py. It should turn names like "Bill Length (mm)" into lower snake_case (bill_length_mm) and come with a test. Name the branch and the rules in the prompt itself, so they don't depend on the agent remembering.

1 · Kickoff (explore, then plan)

We're on branch standardize-columns. Never commit to main.
First explore: read clean.py and test_clean.py. Then propose a plan for a
standardize_columns(df) function that converts column names to lower
snake_case (e.g. "Bill Length (mm)" -> "bill_length_mm").
Don't write any code until I approve the plan.

2 · Implement and commit

Plan approved. Implement it and add a pytest test in test_clean.py.
Run pytest. Make small commits with descriptive messages on this branch.

3 · Ship

Tests pass. Push this branch and open a pull request against main with
gh pr create. Summarize the change and how you tested it in the description.

Install and log in to the gh CLI first. The best-practices guide notes that Claude "knows how to use it for creating issues, opening pull requests, and reading comments."1

Review before you merge

An agent can make many commits quickly. Your job is to read them. Three commands, run on the agent branch, show everything:

$ git log --oneline main..HEAD   # the commits this branch adds
$ git diff main...HEAD          # only the changes made on this branch
$ git diff main...HEAD --stat   # which files, how much

The three dots matter. git diff A...B compares from the point where the branches split, so you see only what the branch changed, the same view a pull request shows.6 Inside Claude Code, /diff shows the changes and /code-review "checks the current diff for correctness bugs."5

For a stronger review, use a second, fresh session. Claude Code's guide suggests a writer/reviewer pattern because "A fresh context improves code review since Claude won't be biased toward code it just wrote."1

Review the diff of this branch against main (git diff main...HEAD).
Look for bugs, missing edge cases, and untested behaviour. Don't edit files.

What the agent's commits look like

By default, Claude's commits carry a git trailer such as Co-Authored-By: Claude … <noreply@anthropic.com>. Pull requests it opens end with "🤖 Generated with Claude Code." You can change both with the attribution setting (attribution.commit, attribution.pr).4 The trailer makes agent-written commits easy to spot in git log.

Undo: checkpoints are not git

Claude Code takes a checkpoint of your code before each prompt. You can restore it with /rewind or by pressing Esc twice.3 That's handy for undoing the last turn, but the docs are blunt: checkpoints are "Not a replacement for version control."3 In particular, "Checkpointing does not track files modified by Bash commands" (e.g. rm, mv, cp), and most subagent edits aren't restored either.3

SituationDo thisWhy
Claude's last turn made a bad file edit and you want the previous state back/rewind (or Esc Esc) → restore codeA checkpoint was taken before that prompt.3
Claude moved or deleted files with Bash (rm, mv)Use git: git restore <file>, or discard the branchCheckpoints don't track Bash file changes.3
One file has bad uncommitted changesgit restore clean.pyRestores the file in the working tree from git.9
The whole experiment is bad, commits and allgit switch main, then git branch -D standardize-columns-D force-deletes an unmerged branch.7 main never moved.
The work is goodPush, open a PR, let CI run, squash-mergeThe normal path from lessons 4–5.

Claude Code's /branch command does not create a git branch. It branches the conversation ("Create a branch of the current conversation at this point").5 For a git branch, use git switch -c or ask Claude to create one.

Bonus: @claude on GitHub

Claude Code can also work from GitHub itself. Mention @claude in a pull request or issue comment "to have Claude analyze code, implement changes, and push commits."8 Run /install-github-app in Claude Code to set it up. It pushes a branch with the workflow files and a pull request ready to create, so even the setup arrives on a branch.8 One gotcha: "GitHub doesn't trigger workflows on commits made with the default GITHUB_TOKEN". Commits pushed by the action that way won't run your CI unless you configure it.8

Do it for real

In your penguins-lab repository (with the CI workflow from lesson 5):

Check yourself

Claude ran a Bash script that deleted and moved files. Can /rewind bring them back?

Checkpointing does not track files changed by Bash commands. Committed work is safe in git, so restore or discard with git.

On the agent branch, what does git diff main...HEAD show?

Three dots diff from the merge base, so you see only what the branch changed. It's the same view a pull request shows.

What does Claude Code's /branch command create?

/branch forks the conversation. Git branches come from git switch -c, or from asking Claude to run it.

The agent's experiment on try-polars is a mess (three commits, not merged). Best cleanup?

git switch main, then git branch -D try-polars. The commits never touched main, so there is nothing to revert.

Command drills

Create and switch to the agent branch standardize-columns.

List, one line each, the commits on the current branch that aren't on main.

Show only the changes the current branch made since it split from main.

You're on main. Throw away the unmerged branch try-polars.

Read Claude Code's Best practices guide, especially "Explore first, then plan, then code" and "Run multiple Claude sessions." It's the official playbook this lesson's loop comes from (about 15 minutes).
Ask Claude: "Walk me through what you'd do on a new branch for this task before you touch any files," or "Show me the commits on this branch that aren't on main and explain each one." Making it explain its own diff is a great review habit.

Sources

  1. Claude Code docs, Best practices (explore → plan → implement → commit; use CLI tools; run multiple sessions; rewind with checkpoints).
  2. Claude Code docs, Common workflows — Create pull requests.
  3. Claude Code docs, Checkpointing (how checkpoints work; limitations; not a replacement for version control).
  4. Claude Code docs, Settings reference — attribution and includeGitInstructions.
  5. Claude Code docs, Commands (/branch, /diff, /code-review).
  6. Git reference, git-diff (A...B semantics).
  7. Git reference, git-branch (-d vs -D).
  8. Claude Code docs, Claude Code GitHub Actions.
  9. Git reference, git-restore.