Языки: EN RU

Git, Commits, and Pull Requests

Claude Code understands git in a way most IDE plugins don't: rather than simply calling git commit, it builds a meaningful workflow — deciding what to stage, crafting messages based on the context of changes, and creating branches and PRs at the right moments. But this only works if you integrate git into the process explicitly, rather than leaving it "for later."

The previous article on Best Practices and Code Organization Patterns established the principle: "commit before every major step." This article covers how to do that in practice, and what else Claude Code can do in a git context.


Commits: the agent writes the message, not you

The most obvious use case is to have Claude Code not only write the code, but immediately commit it with a meaningful message. The difference from just running git commit -m "fix" is significant.

Give the agent a task like this:

Implement CSV file parsing in src/parsers/csv.ts.
After implementation and green tests (`npm test -- csv`) —
commit the changes with a meaningful conventional commits message.

Claude Code will examine the diff, understand the essence of the changes, and write something like:

feat(parsers): add CSV parser with delimiter auto-detection

- Supports comma, semicolon, and tab delimiters
- Handles quoted fields with embedded newlines
- Returns typed rows via generic parameter

This isn't a template — the agent formulates the message based on the actual diff content. If a change touches several unrelated things, Claude Code will often suggest splitting it into two commits on its own.

One important note: by default, the agent will ask for confirmation before running git commit. This behavior is controlled by the permissions mode — in the standard (default) mode, you confirm each destructive or irreversible action. For git operations, this is reasonable: a commit with the wrong content is worse than a one-second pause.

Проверь себя
Why does Claude Code ask for confirmation before `git commit` by default, even though it can write code without pausing?

Staging: the agent decides what to include

Claude Code can run git add selectively. If the working directory contains several modified files but only one task needs to be committed, be specific:

Commit only the changes related to the auth module.
Leave files in src/utils/ alone for now — that work is unfinished.

The agent will check git status, select the relevant files, and run git add precisely. If it spots something extra in the diff, it will ask whether to include it.

A useful pattern: before starting a large task, ask the agent to check for any uncommitted changes and, if there are any, either commit them or stash them:

Check git status. If there are uncommitted changes — ask what to do
with them before starting the task.

This prevents situations where the agent mixes two different sets of changes into a single commit.


Branches: isolation at the git level

For any task longer than 15 minutes or touching more than 2–3 files — create a branch. This isn't bureaucracy; it's insurance: you can compare against main, roll back, or hand it off for review without risking the main branch.

Create a branch feature/export-csv from main,
implement CSV export (task in CLAUDE.md under tag #export),
commit in steps.

Claude Code will run git checkout -b feature/export-csv main and work in isolation. If something goes wrong — git checkout main instantly returns you to the original state.

flowchart TD A[New task] --> B[git checkout -b feature/name] B --> C[Claude Code: research] C --> D[Claude Code: step implementation] D --> E{Tests green?} E -->|No| D E -->|Yes| F[git commit with a meaningful message] F --> G{Task complete?} G -->|No — next step| D G -->|Yes| H[git diff main...HEAD --stat] H --> I[gh pr create] I --> J[Review / @claude in PR] J --> K[Merge into main]
flowchart TD
    A[New task] --> B[git checkout -b feature/name]
    B --> C[Claude Code: research]
    C --> D[Claude Code: step implementation]
    D --> E{Tests green?}
    E -->|No| D
    E -->|Yes| F[git commit with a meaningful message]
    F --> G{Task complete?}
    G -->|No — next step| D
    G -->|Yes| H[git diff main...HEAD --stat]
    H --> I[gh pr create]
    I --> J[Review / @claude in PR]
    J --> K[Merge into main]
A typical Claude Code git workflow: from branch creation to merge

Worktrees: multiple tasks in parallel

Git worktrees are one of the most underrated features in the context of Claude Code. A worktree is a separate working directory tied to the same git repository, with its own branch. Multiple worktrees can exist simultaneously.

The practical use case: you're running two tasks in parallel in different terminal windows, each in its own worktree and its own Claude Code session.

# Create a worktree for the second task
git worktree add ../myproject-auth feature/oauth-integration

# In the first window — working in the main directory
cd ~/myproject
claude

# In the second — in the worktree
cd ~/myproject-auth
claude

Both agents work independently, without file conflicts (each has its own working directory), but share git history. When the task is done — git worktree remove ../myproject-auth removes the directory while the branch remains.

This is especially valuable when one task is awaiting review and you don't want to lose time. Instead of git stash with its potential conflicts — clean isolation through worktrees.

Проверь себя
Why is git worktree better than `git stash` when switching between tasks in the context of Claude Code?

Pull Requests: from commit to PR

Claude Code can create PRs via the gh CLI (GitHub CLI) or through the built-in GitHub integration. For the CLI approach, all you need is:

The task is done, tests are green. Create a PR to main with a description
of the changes: what was done, why it was done that way, and what to pay
attention to during review. Use gh pr create.

The agent will compose a PR description based on the commits and diff — not a boilerplate one, but based on the actual content of the changes. It looks something like this:


::widget{id="rc-3"}


::widget{id="rc-2"}


::widget{id="rc-1"}

## What
Adds CSV export for the Users table via `/api/export/users.csv`.

## Why
Product requested bulk data export for enterprise customers (#234).
Chose CSV over XLSX: no external dependencies, smaller output.

## Notes for reviewer
- `src/export/csv.ts` handles streaming for large datasets (>10k rows)
- Rate-limited to 1 request/minute per user to prevent DB overload
- Migration not needed — uses existing User model

If the repository has the GitHub integration set up via @claude (installed with the /install-github-app command), you can go further: mention @claude in a PR comment and the agent will launch in the cloud, review the code, and leave feedback. That's already the level of GitHub Actions and Automated Code Review.


Resolving conflicts

Conflicts during merge or rebase are a task Claude Code handles better than you might expect. The agent can read conflict markers (<<<<<<<, =======, >>>>>>>) and understand which change is logically correct.

A working approach:

During git merge, conflicts appeared in src/auth/session.ts
and src/api/routes.ts. Resolve the conflicts: in auth/session.ts, give
priority to changes from the feature branch; in routes.ts — combine both.
After resolving — run npm test and commit.

Without context, the agent risks guessing incorrectly. With context about what takes priority — it handles it accurately. The key point: don't ask the agent to resolve conflicts "however it thinks is best" without specifying priorities. It has no business context, only code.

For complex conflicts, the pattern from Subagents and Context Isolation is useful: one subagent examines the feature branch, a second examines main, and a third makes the decision with both summaries in context.


Integrating into a team workflow

A few practical rules that help avoid friction with the team.

Name branches meaningfully from the first prompt. The agent uses the branch name in commit messages and PRs. feature/csv-export-users is better than feature/task-42.

One PR — one task. If the agent finds a bug in the process and wants to fix it along the way — ask it to create a separate branch and a separate PR. This is standard review practice, and the agent understands it.

Set --base explicitly. When creating a PR via gh pr create, specify the target branch:

Create a PR to the develop branch (not main) via gh pr create --base develop.

Review the diff before the PR. Ask the agent to show git diff main...HEAD --stat before creating the PR — this lets you see the scope of changes and catch any accidentally included files.

# The agent will run something like:
git diff main...HEAD --stat

# Typical output:
src/parsers/csv.ts           | 87 ++++++++++++++++
src/parsers/csv.test.ts      | 43 ++++++++
src/parsers/index.ts         |  3 +
3 files changed, 133 insertions(+)

If node_modules or .env showed up in the diff — better to catch it here than after pushing.

Проверь себя
Before creating a PR, the agent runs `git diff main...HEAD --stat`. Why `...` (three dots) instead of `..` (two dots)?

See also

  • Best Practices and Code Organization Patterns — principles of context discipline and task decomposition that underpin the git workflow
  • Subagents and Context Isolation — the Writer/Reviewer pattern and parallel processing via subagents
  • Headless Mode and CLI Scripting — automating git operations in CI/CD via claude -p
  • GitHub Actions and Automated Code Review — integrating @claude into PR reviews via GitHub Actions
  • Cloud Agents: Web, Routines, and Background Tasks — running agents on git events in the cloud
  • Typical Workflows: Research, Plan, Implementation — the full cycle from task to commit