Claude Code Git Workflow: Safe Branches, Small Commits, CI, and Team Handoffs
A practical Claude Code Git workflow for clean branches, commits, rebase, CI gates, rollback, and team handoff.
The faster Claude Code writes code, the more disciplined your Git workflow has to become. AI can produce a useful diff in minutes, but it can also mix unrelated files, generate oversized commits, resolve conflicts without understanding intent, or push before local checks have run.
This guide gives you a practical Claude Code Git workflow for solo and team development: a clean branch loop, small commits, a review gate, conflict handling, worktree hygiene, safe rollback, CI before push, and daily handoff notes. It also explains beginner Git terms such as staging, commit, and rebase in plain language.
Related ClaudeCodeLab follow-ups: Git conflict resolution with Claude Code, advanced GitHub Actions, and the review workflow checklist. Official references worth keeping open are Claude Code hooks, Claude Code headless mode, Git user manual, Git rebase, GitHub Actions workflow syntax, and pre-commit.
Git terms in plain language
Your working tree is the place where files are currently edited. Claude Code writes into this area. The staging area is the “next commit basket.” Running git add does not permanently save work; it chooses which changes should go into the next commit.
A commit is a named snapshot of the staged changes. A good commit is small enough that a teammate can understand the reason in one sitting. A rebase takes your branch commits and places them on top of the latest base branch. It keeps history readable, but rewriting a branch that other people already use can break their work.
Claude Code should not be treated as only a code generator. In a strong workflow it also reads the diff, proposes what to stage, drafts a commit message, explains conflicts, runs local proof commands, and leaves a handoff that another human can verify.
flowchart LR
A["Write the goal"] --> B["Update main and create branch"]
B --> C["Implement a small slice"]
C --> D["Read diff and choose staging"]
D --> E["Review gate and local CI"]
E --> F["Small commit"]
F --> G["Rebase or open PR"]
G --> H["Handoff and rollback note"]
Start with a clean branch loop
Before asking Claude Code to edit anything, make the worktree understandable. “Clean” does not always mean zero changes. It means there are no unrelated changes mixed into this task.
git status --short
git fetch origin
git switch main
git pull --ff-only origin main
git switch -c feature/checkout-coupon-validation
git status --short
In PowerShell, a date-stamped branch name is useful when several sessions run in parallel.
$topic = "checkout-coupon-validation"
$date = Get-Date -Format "yyyyMMdd"
git fetch origin
git switch main
git pull --ff-only origin main
git switch -c "feature/$date-$topic"
git status --short
The first Claude Code prompt should define scope before implementation.
Goal: add coupon expiry validation to checkout.
Scope: edit only src/checkout, src/coupons, and matching tests.
Do not stage, commit, push, or edit unrelated files.
Before editing, read package.json and existing checkout tests.
After editing, show git diff --stat and the exact test commands you ran.
This prevents a common failure mode: the implementation is correct, but the diff contains local settings, generated files, or content from a different task. In ClaudeCodeLab publishing work, Masa has seen article edits accidentally pick up product-page drafts and script changes. The fix was not a smarter model; it was a stricter Git loop.
Stage deliberately and commit small
git add -A is convenient, but it is too broad for AI-assisted work. It can stage temporary files, unrelated edits, or half-finished experiments. Prefer reading the diff first and staging exact paths.
git diff --stat
git diff
git add src/checkout/validateCoupon.ts
git add tests/checkout/validateCoupon.test.ts
git diff --staged --stat
git diff --staged
A commit message should explain the change and the user impact. Conventional Commits style is useful because it makes history searchable.
git commit -m "feat(checkout): validate coupon expiry before payment"
For a content or workflow change, add a body.
git commit -m "fix(content): keep Claude Code Git workflow CTA localized" -m "Updates the localized article body, internal links, and review checklist so translated pages follow the same Git workflow."
You can ask Claude Code to draft the message without allowing it to commit.
Read only the staged diff.
Propose one Conventional Commits message.
Do not run git commit.
Mention the user impact in the body if the change affects readers or customers.
Put Git rules in CLAUDE.md
If you repeat the same warning in every session, move it into CLAUDE.md. Think of CLAUDE.md as operating instructions for your AI pair programmer. It is not a user-facing README; it is the local rulebook for how work should happen in the repository.
# Claude Code Git rules
- Start every coding task with `git status --short` and report unrelated dirty files.
- Do not run `git add -A`, `git commit`, `git push`, `git reset --hard`, or `git clean -fd` unless the user explicitly asks.
- Keep commits small: one behavior change, one test update, or one content slug at a time.
- Before proposing a commit, show `git diff --stat` and `git diff --staged --stat`.
- If a conflict appears, explain both sides before editing the conflicted file.
- Run the closest local checks before push: lint, typecheck, test, build, or article metadata checks.
- Leave a handoff note with changed files, commands run, failing checks, and rollback option.
For team use, add a hook that blocks risky Git commands before they execute. Claude Code hooks are user-defined commands that run at lifecycle events such as tool use.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(git *)",
"command": "node .claude/hooks/block-dangerous-git.mjs"
}
]
}
]
}
}
// .claude/hooks/block-dangerous-git.mjs
import process from "node:process";
let raw = "";
for await (const chunk of process.stdin) raw += chunk;
const input = JSON.parse(raw || "{}");
const command = input.tool_input?.command ?? "";
const blocked = [
/git\s+reset\s+--hard\b/,
/git\s+clean\s+-[^\s]*f/,
/git\s+push\s+--force(?!-with-lease)/,
/git\s+checkout\s+--\s+\./,
/git\s+restore\s+\.\b/
];
if (blocked.some((pattern) => pattern.test(command))) {
process.stderr.write(`Blocked risky Git command: ${command}\n`);
process.exit(2);
}
Hooks are a guardrail, not a complete governance system. Humans can still run commands outside Claude Code, and local machine settings can differ. Use hooks together with CLAUDE.md, review gates, and CI.
Run CI before push
Waiting for remote CI after a push is slower than catching basic failures locally. Give Claude Code a preflight command that runs only the checks available in the project.
// scripts/claude-git-preflight.mjs
import { execSync } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
const run = (command) => {
console.log(`\n$ ${command}`);
execSync(command, { stdio: "inherit", shell: true });
};
run("git diff --check");
run("git diff --cached --check");
run("git status --short");
const pkg = existsSync("package.json")
? JSON.parse(readFileSync("package.json", "utf8"))
: { scripts: {} };
for (const script of ["lint", "typecheck", "test", "build"]) {
if (pkg.scripts?.[script]) run(`npm run ${script}`);
}
Run it before push:
node scripts/claude-git-preflight.mjs
For Python or Go repositories, use the same idea with ruff check, pytest, or go test ./.... The key is not the tool name. The key is that Claude Code must report what actually ran.
After implementation, run the local preflight.
If a command fails, stop and explain the first failing command, likely cause, and smallest next fix.
Do not push until the preflight is green.
Add pre-commit and GitHub Actions gates
pre-commit runs checks before a commit is created. It gives humans and Claude Code the same local gate.
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: git-diff-check
name: git diff whitespace check
entry: git diff --check
language: system
pass_filenames: false
- id: npm-test
name: npm test when available
entry: node scripts/claude-git-preflight.mjs
language: system
pass_filenames: false
python -m pip install pre-commit
pre-commit install
pre-commit run --all-files
Then repeat the important checks in GitHub Actions so every pull request is verified on a clean runner.
# .github/workflows/claude-code-pr-gate.yml
name: Claude Code PR Gate
on:
pull_request:
branches: [main]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: git diff --check origin/main...HEAD
- run: npm run lint --if-present
- run: npm run typecheck --if-present
- run: npm test --if-present
- run: npm run build --if-present
When CI fails, do not paste an entire log into Claude Code first. Provide the first failing command, the error block, and the files involved. That keeps the repair loop short.
Handle conflicts and rebase with intent
A conflict means Git cannot automatically choose between two edits to the same area. Do not ask Claude Code to “just keep both” unless that is truly the desired behavior. Ask it to explain the intent on both sides first.
git fetch origin
git rebase origin/main
git status --short
git diff --name-only --diff-filter=U
Prompt Claude Code like this:
We are in a rebase conflict.
For each conflicted file, explain what our branch changed and what origin/main changed.
Resolve only after explaining the business intent.
After editing, run the narrowest relevant test.
Do not continue the rebase until I approve the resolved diff.
After the fix:
git add src/checkout/validateCoupon.ts
npm test -- --runInBand validateCoupon
git rebase --continue
If the resolution looks wrong, abort:
git rebase --abort
If a branch has already been pushed and you rewrite it, use --force-with-lease only under your team rules. The beginner mistake to avoid is force-pushing over work that somebody else added.
Roll back safely
Rollback should leave evidence. For shared commits, prefer git revert because it creates a new commit that undoes the earlier one.
git log --oneline -5
git revert --no-edit HEAD
git status --short
For uncommitted work, target exact paths.
git restore --staged src/checkout/validateCoupon.ts
git restore src/checkout/validateCoupon.ts
Before a larger rollback, create a backup branch.
$sha = git rev-parse --short HEAD
git switch -c "backup/before-rollback-$sha"
git switch -
git revert --no-edit HEAD
Use this prompt before letting Claude Code plan a rollback:
Suggest a rollback plan.
Prefer git revert for shared commits.
Do not use reset --hard or clean -fd.
List exactly which files or commits would be affected.
Concrete use cases
Use case 1: solo feature work. Create a feature/yyyyMMdd-topic branch, give Claude Code exact files and tests, keep the commit to one behavior change, and run local preflight before push. If the result is wrong, the rollback path is simple.
Use case 2: team pull requests. Split roles. The implementation session edits but does not commit. The review session reads only the staged diff. A human checks PR title, CI, risk, and rollback before push. This prevents AI momentum from turning into unreviewed main-branch risk.
Use case 3: content and product updates. On ClaudeCodeLab, articles, Gumroad links, training CTAs, and internal links affect revenue. A content branch should be scoped by slug and locale. Check description length, hero image, CTA links, mojibake, and localized body, not only build success.
Use case 4: long refactors. Do not ask Claude Code to rewrite the whole system in one commit. Add tests first, change internals second, remove old code last. Tell Claude Code when public APIs must stay stable until a later commit.
Failure modes to watch
| Failure | Why it happens | Prevention |
|---|---|---|
git add -A stages unrelated files | AI work creates or touches more than the task needs | Stage exact paths after git diff --stat |
| Giant commit | Implementation, tests, copy, and config happen together | Keep one purpose per commit |
| Vague conflict resolution | The model merges text without preserving intent | Require an ours/theirs explanation first |
| Bad rebase push | Local history no longer matches remote | Use team-approved --force-with-lease only |
| Red PR after push | Local checks never ran | Run scripts/claude-git-preflight.mjs |
| Destructive rollback | reset --hard removes evidence | Prefer git revert for shared commits |
| Hook overconfidence | Hooks do not cover every human action | Combine hooks with review and CI |
Masa’s practical lesson from ClaudeCodeLab publishing work was simple: the most expensive mistakes were not syntax errors. They were unexplained diffs. A file changed for a reason nobody could reconstruct is a workflow failure even when the build passes.
Leave a daily handoff
A handoff should be short, factual, and restartable. It is not a diary. It is the evidence another person needs to continue safely.
## Handoff: 2026-06-02
Branch: feature/20260602-checkout-coupon-validation
Goal: validate coupon expiry before payment authorization
Changed:
- src/checkout/validateCoupon.ts
- tests/checkout/validateCoupon.test.ts
Checks:
- npm run lint: passed
- npm test -- --runInBand validateCoupon: passed
- npm run build: not run, no UI/build config touched
Risk:
- Coupon timezone boundary still needs one integration test.
Rollback:
- Revert commit `abc1234` if production checkout rejects valid coupons.
Prompt:
Write a daily handoff.
Include branch, goal, changed files, checks run, checks not run, risk, and rollback.
Do not claim a command passed unless it was actually run in this session.
Turn the workflow into a real operating system
A Git workflow article is weak if it ends as a command list. Readers need a repeatable operating model for their repository. Solo builders can start with the free Claude Code cheatsheet and keep the daily commands nearby. If you want reusable prompts, CLAUDE.md rules, and review templates, compare the ClaudeCodeLab products.
For teams, the real work is deciding branch naming, commit size, CI gates, permissions, review ownership, rollback behavior, and handoff format against the actual repository. That is where Claude Code training and consultation is useful: the output is not a generic prompt, but a workflow your team can use repeatedly.
What happened when we tried it
Using this Git loop on ClaudeCodeLab content updates changed the review from “reread everything” to “inspect the slug, locales, metadata, CTA, and diff scope.” The biggest wins were git diff --staged --stat and the handoff note. They make it obvious what was verified and what remains risky. Claude Code is most valuable when it writes quickly and leaves proof that the next person can trust.
Free PDF: Claude Code Cheatsheet
Enter your email and download the one-page Claude Code cheatsheet for commands, review habits, and safe workflows.
We handle your data with care and never send spam.
Level up your Claude Code workflow
Start with the free PDF, use Gumroad guides when you need repeatable workflows, and book consultation when rollout or revenue paths need human judgment.
About the Author
Masa
Engineer focused on practical Claude Code workflows. Runs claudecode-lab.com, a 10-language technical media site.
Related Posts
Claude Code Permission Safety Ladder: Expand Access Without Losing Control
A beginner-friendly ladder for moving Claude Code from read-only to limited edits, proof commands, and deploy checks.
Claude Code Small PR Proof Pack: Make Tiny Changes Reviewable
A practical proof pack for Claude Code PRs: diff, checks, public URL, CTA path, and rollback note.
Claude Code Review Gate Before Commit: Diff, Tests, Public URL, and CTA Checks
A commit-time review gate for Claude Code work: diff scope, build, public URL, revenue CTA links, missing tests, and unrelated files.
Related Products
Claude Code Quick Reference Cheatsheet
A free one-page reference for daily Claude Code work.
Keep the essential commands, file-reference patterns, CLAUDE.md reminders, prompting habits, review cues, and debugging workflow notes next to your editor.
50 Battle-Tested Claude Code Prompt Templates
Copy, paste, ship. 50 production-ready prompts.
Use proven prompts for code review, refactoring, testing, documentation, debugging, architecture, and incident response.