Applied Intelligence
Module 6: Version Control with Agents

Branching Strategies for Agent Work

Branching strategies for agent work

Branches are isolation boundaries. This has always been true, but the stakes change when agents generate code fast and the outcomes are uncertain. Branching strategies for Agentic Software Development look familiar feature branches, experimental spikes, squash merges but they adapt to new realities: more parallel work, more throwaway code, and more frequent decisions about what to keep.

Feature branch patterns

The feature branch model remains the foundation. Every agent task starts on its own branch, isolating generated code from the main codebase until a human reviews it.

Different tools enforce this differently. GitHub Copilot Coding Agent requires branches to begin with the copilot/ prefix and physically cannot push to main or master this constraint is not configurable. As of October 2025, these branches use descriptive names like copilot/add-theme-switcher rather than the UUIDs from earlier versions.

Claude Code and Codex leave branch naming to the developer but the recommendation is clear: create a fresh branch before starting any agent session:

# Standard pattern: create branch, then start agent
git checkout -b feat/profile-refactor
claude

This gives you a safety net. If the agent produces unusable code, discarding the branch costs nothing. If the work succeeds, the branch integrates through normal review processes.

For teams, branch prefixes clarify ownership and origin:

feat/jsmith/user-auth         # Human-driven feature
ai/claude/api-refactor        # Agent-driven work
ai/copilot/fix-memory-leak    # Copilot Coding Agent (auto-named)
spike/jsmith/auth-approaches  # Exploratory work

The ai/ prefix signals that the branch contains agent-generated code, which may need different review attention. Some teams require this prefix for audit trail purposes.

Experimental branches for risk isolation

Agent work often involves exploration. The agent may try several approaches before finding one that works, or you may want to compare different implementation strategies. Experimental branches contain this exploration without polluting the main branch namespace.

The spike branch pattern works well for time-boxed exploration:

# Create spike branch for exploration
git checkout -b spike/auth-approaches main

# Let agent explore different auth implementations
claude "Implement JWT authentication with refresh tokens"

# If successful, the work moves to a real feature branch
# If not, the branch is simply deleted

Spike branches carry an implicit expectation: the code may be thrown away. This framing reduces the pressure to preserve suboptimal work just because effort was invested.

For more structured exploration, create parallel branches to compare approaches:

# Create three worktrees for parallel exploration
git worktree add ../auth-jwt -b spike/auth-jwt
git worktree add ../auth-session -b spike/auth-session
git worktree add ../auth-oauth -b spike/auth-oauth

# Run agents in each to implement different approaches
# Compare results, keep the best, discard the rest

This pattern treats agent-generated code as potentially disposable. With generation costs measured in minutes rather than hours, trying multiple approaches in parallel often beats iterating on a single approach.

Autonomous agent branching

Autonomous agents like Copilot Coding Agent create their own branches as part of their workflow. Understanding this pattern helps when integrating these tools into existing branch strategies.

The Copilot Coding Agent workflow:

  1. User assigns an issue to Copilot (via GitHub, VS Code, or the Agents panel)
  2. Agent spins up a virtual environment and clones the repository
  3. Agent creates a copilot/ prefixed branch from the selected base branch
  4. Agent opens a draft pull request with an initial empty commit
  5. Agent pushes commits as it works, logging key steps in the PR
  6. When finished, agent requests review from the user

The draft PR model keeps agent work visible but clearly marked as incomplete. GitHub Actions workflows will not run until a human clicks "Approve and run workflows" this prevents untested agent code from hitting CI/CD pipelines.

Teams can select any branch as the base branch, not just main. This makes it possible to layer agent tasks on existing feature branches, useful when breaking large features into sub-tasks.

For repositories with branch protection rules, Copilot can be configured as a bypass actor in rulesets. This lets the agent push to branches where it otherwise could not comply with rules like signed commits. The bypass applies only to the technical constraint; human review requirements stay in place.

Throwaway work branches

Not all branches are meant to survive. Throwaway branches contain work that is explicitly expected to be discarded spikes that failed, prototypes that informed decisions but are not production-ready, or exploration that proved a negative result.

The mental shift matters: treating branches as cheap encourages experimentation. GitClear research shows AI-generated code has a 41% higher churn rate than human-written code but this is not necessarily a problem. It reflects a development style that generates more variations to find the right solution.

A workflow pattern for throwaway work:

# Create throwaway branch with clear naming
git checkout -b throwaway/jsmith/perf-experiment

# Work with agent
claude "Try three different approaches to optimize this query"

# Evaluate results
# Option A: Work is good, rename branch and continue
git branch -m feat/query-optimization

# Option B: Work is not usable, delete cleanly
git checkout main
git branch -D throwaway/jsmith/perf-experiment

For branches that contain valuable learnings even if the code is not usable, archive rather than delete:

# Preserve the branch as a reference
git tag archive/perf-experiment-2025-01 throwaway/jsmith/perf-experiment

# Now safe to delete the branch
git branch -D throwaway/jsmith/perf-experiment

# The code remains accessible via the tag
git log archive/perf-experiment-2025-01

This preserves the ability to revisit decisions later useful during post-mortems or when a similar problem arises.

Integration strategies

How agent branches merge into the main codebase affects both history readability and review quality.

Squash merge works best for most agent-generated branches. Agent work often produces many incremental commits as the agent iterates. Squashing these into a single commit on merge yields a cleaner history where each commit represents a complete, reviewed change:

# Platform-level squash (GitHub, GitLab)
# Configured in repository settings

# Manual squash before merge
git checkout main
git merge --squash feat/profile-refactor
git commit -m "Add profile refactoring with caching"

The previous section on history readability covered squash-before-PR patterns in detail. For agent work, squash merge at the platform level often makes more sense than manual squashing because it enforces consistent behavior regardless of who pushes.

Merge commits preserve full history. This works better when auditability matters regulated industries, open-source projects tracking contributor attribution, or teams that debug by tracing through commit history. The tradeoff is a more complex history that includes all the agent's iteration steps.

Rebase before merge produces a clean linear history but requires more discipline. The rule from earlier applies: never rebase commits that exist on the remote unless you are working solo on that branch. For agent branches, this typically means rebase is only safe before the first push.

The rebase-before-PR model

Some teams require feature branches to be rebased onto the latest main before opening a pull request. This ensures the PR shows only the changes introduced by the feature, without merge commits from main.

# Update local main
git checkout main
git pull

# Rebase feature branch onto main
git checkout feat/agent-feature
git rebase main

# Force push (safe because this is a solo branch)
git push --force-with-lease

# Now open PR

The --force-with-lease flag provides safety: it refuses to push if the remote branch has been updated since the last fetch. This prevents accidentally overwriting work pushed by someone else or by an autonomous agent continuing to work.

For agent branches that may still be receiving commits, coordinate with the agent's workflow. Copilot Coding Agent expects to push to its own branch and may conflict with manual rebases during an active session.

Branch lifecycle in ASD

A typical branch lifecycle in Agentic Software Development follows this path:

Creation: New branch for a specific task, with clear naming convention. The developer owns this decision even autonomous agents create branches based on human-assigned issues.

Development: Agent works and makes commits; human reviews incrementally or waits for completion. Context stays fresh because the branch is isolated.

Stabilization: Agent work is complete. The human cleans up, runs final tests, verifies the change does what was intended.

Integration: Squash merge or rebase-and-merge into main. The human makes this call.

Cleanup: Branch deleted, worktree removed if applicable. Done.

The agent drives development; the human owns everything else. This separation prevents agents from merging their own work a guardrail present in Copilot Coding Agent (cannot merge PRs) and the recommended practice for Claude Code and Codex workflows.

The branch becomes the unit of agent work. Starting agents on main, running multiple agents on the same branch, or skipping review before integration all introduce risks that the branch-per-task model avoids.

On this page