Skip to main content

Git Workflow, Branching, and Worktrees

Date: 2026-03-01 Status: Active


Problem Statement

SecurityV0 uses multiple Claude Code agents working in parallel across five repositories (sv0-platform, sv0-connectors, sv0-documentation, sv0-website, sv0-skills). Without clear rules, agents can:

  1. Push directly to main — breaking production or overwriting each other's work
  2. Corrupt shared state — two agents editing the same working tree simultaneously
  3. Force-push or merge — violating the rebase workflow and destroying history
  4. Duplicate effort — starting the same task without knowing another agent is already on it

This runbook defines the branching strategy, worktree isolation model, and safety guardrails that prevent these problems.


Branching Strategy

Rebase Workflow

All SecurityV0 repositories use a rebase workflow — no merge commits. This keeps history linear and readable.

# Before creating a PR, rebase onto latest main
git fetch origin
git rebase origin/main

# If conflicts occur, resolve them file by file
git add <resolved-file>
git rebase --continue

Commits are SSH-signed via 1Password. Agents use conventional commit messages (docs:, fix:, feat:, refactor:, test:, chore:).

Branch Naming Convention

{category}/{issue-number}-{short-description}
CategoryOutputExample
research/Documentation, analysisresearch/42-execution-evidence-feasibility
impl/Code changes (PR)impl/55-evidence-grade-materializer
infra/Config, deployment, CI/CDinfra/60-slack-bot-setup
fix/Bug fixesfix/71-tenant-header-missing
docs/Documentation-only changesdocs/git-workflow-worktree-runbook

If no GitHub Issue exists yet, omit the issue number: docs/git-workflow-worktree-runbook.

Protected Branches

BranchRule
mainNever push directly. All changes via PR.
dev (if used)Never push directly. All changes via PR.

Agents create feature branches, push those, and open PRs with gh pr create. Humans review and merge.

GitHub Free limitation: The SecurityV0 org is on GitHub Free, which does not support repository rulesets or branch protection rules. The protected branch rules above are enforced locally via .claude/settings.json deny rules (see Agent Git Safety Rules below) rather than server-side. A human with push access can still push directly to main — the deny rules only constrain Claude Code agents. Consider upgrading to GitHub Pro ($4/user/month) if server-side enforcement is needed.


Worktrees for Multi-Agent Parallelism

When Worktrees Are Needed

ScenarioWorktree?Why
One agent, one repoNoNo conflict possible
Multiple agents, different reposNoEach repo has its own .git — fully isolated
Multiple agents, same repoYesAgents would corrupt each other's working tree

How Claude Code Worktrees Work

Claude Code has a native EnterWorktree tool. When an agent enters a worktree:

  1. A new directory is created at .claude/worktrees/<name>/
  2. A new branch is created from HEAD
  3. The agent's working directory switches to the worktree
  4. The agent works in full isolation — edits, staging, and commits are separate
  5. On session exit, the user is prompted to keep or remove the worktree

The worktree shares the git object store with the main clone — it's lightweight (no full re-clone).

Worktree Lifecycle

┌─────────────────────────────────────────────────────────┐
│ 1. Agent starts session │
│ └─ User instructs: "use a worktree" or agent │
│ detects multi-agent scenario │
│ │
│ 2. Agent enters worktree │
│ └─ EnterWorktree creates .claude/worktrees/<name>/ │
│ └─ New branch created from HEAD │
│ │
│ 3. Agent works in isolation │
│ └─ Edits files, runs tests, commits │
│ └─ Pushes feature branch to origin │
│ │
│ 4. Agent creates PR │
│ └─ gh pr create --base main │
│ │
│ 5. Session ends │
│ └─ User prompted to keep or remove worktree │
│ └─ If PR is merged, worktree can be safely removed │
└─────────────────────────────────────────────────────────┘

Worktree Branch Naming

After entering a worktree, rename the auto-generated branch to follow the standard convention:

# Claude Code creates a branch like: worktree-random-name
# Rename it to follow convention:
git branch -m {category}/{issue-number}-{description}

Or provide the name when entering the worktree — Claude Code's EnterWorktree accepts an optional name parameter.

Directory Structure with Worktrees

/Users/<user>/dev/securityv0/
├── sv0-documentation/ # Main clone (Agent A)
│ ├── .claude/
│ │ ├── worktrees/
│ │ │ ├── agent-bob/ # Agent B's isolated copy
│ │ │ └── agent-carol/ # Agent C's isolated copy
│ │ ├── agents/
│ │ ├── skills/
│ │ └── settings.json
│ ├── docs/
│ └── ...
├── sv0-platform/ # Separate repo (no worktree needed)
└── sv0-connectors/ # Separate repo (no worktree needed)

Conflict Resolution

When two agents work on the same repo via worktrees and their PRs touch overlapping files:

  1. First PR merges normally — no conflicts
  2. Second agent rebases before pushing:
    git fetch origin
    git rebase origin/main
    # Resolve any conflicts
    git push --force-with-lease origin {branch}
  3. If conflicts are complex, the second agent should flag it for human review rather than guessing at resolution

Agent Git Safety Rules

.claude/settings.json

Every SecurityV0 repository should include a .claude/settings.json with deny rules that prevent dangerous git operations:

{
"permissions": {
"deny": [
"Bash(git push origin main*)",
"Bash(git push origin dev*)",
"Bash(git push origin HEAD:main*)",
"Bash(git push origin HEAD:dev*)",
"Bash(git push --force*)",
"Bash(git push -f*)",
"Bash(git push * --force*)",
"Bash(git push * -f*)",
"Bash(git merge*)",
"Bash(git reset --hard*)",
"Bash(rm -rf*)",
"Bash(gh pr merge*)"
]
}
}

Rules Explained

RuleWhy
No push to main/devProtected branches — all changes via PR
No force pushPrevents rewriting shared history
No git mergeRebase workflow only — keeps history linear
No git reset --hardPrevents discarding uncommitted work
No rm -rfPrevents accidental deletion of directories
No gh pr mergeAgents create PRs; humans review and merge

Deploying Safety Rules Across Repos

The settings.json file should be committed to .claude/settings.json in every SecurityV0 repository:

  • sv0-platform/.claude/settings.json
  • sv0-documentation/.claude/settings.json
  • sv0-website/.claude/settings.json
  • sv0-connectors/.claude/settings.json — not yet added
  • sv0-skills/.claude/settings.json — not yet added

Cross-Repo Coordination

Different Repos = No Git Conflicts

When agents work on different repos (e.g., one on sv0-platform, another on sv0-connectors), there are no git-level conflicts. The repos are fully independent clones side by side:

/Users/<user>/dev/securityv0/
├── sv0-platform/ # Agent A works here
├── sv0-connectors/ # Agent B works here
├── sv0-documentation/ # Agent C works here
├── sv0-website/ # Agent D works here
└── sv0-skills/ # Shared skills (symlinked to ~/.claude/skills/)

Coordination happens at the task level, not the git level.

GitHub Issues Prevent Duplicate Work

The Team Workflow and Task Tracking runbook defines three mechanisms:

  1. Claim before starting — Agents check for existing GitHub Issues via the UserPromptSubmit hook and create/claim issues before working
  2. Branch naming — Issue number in the branch name makes overlap visible (git branch -r | grep /42-)
  3. Slack digest — Daily bot posts open issues, PRs, and stale items to #sv0-dev

Multi-Repo Tasks

When a task spans multiple repos (e.g., a connector change that requires a platform type update):

  1. Create a GitHub Issue in the primary repo (where most work happens)
  2. Reference it in commit messages and PR descriptions across repos
  3. Each repo gets its own branch and PR — no cross-repo git dependencies
  4. Merge order matters: merge the dependency first (e.g., platform types before connector)

Quick Reference

Starting Work

# Create a feature branch
git checkout -b {category}/{issue-number}-{description}

# If multi-agent, use a worktree instead
# (in Claude Code: "start a worktree")

Before Creating a PR

# Rebase onto latest main
git fetch origin
git rebase origin/main

# Push feature branch
git push -u origin {branch-name}

# Create PR
gh pr create --base main --title "description" --body "details"

What Agents Must Never Do

  • Push to main or dev
  • Force push (--force, -f)
  • Run git merge (rebase only)
  • Run git reset --hard
  • Run rm -rf
  • Merge PRs (gh pr merge) — humans merge