Shared Git State in Parallel Agent Worktrees

Shared Git State in Parallel Agent Worktrees

并行 Agent 工作树中的 Git 共享状态

When deploying multiple AI coding agents across isolated Git worktrees, it is common to assume complete independence. While worktrees provide separate filesystems, working directories, and HEAD pointers, they share a single underlying object database and branch namespace. This shared architecture introduces subtle failure modes when multiple agents execute git commands concurrently. Understanding these shared state hazards prevents unexpected ref corruption and silent failures during automated workflows.

在跨隔离的 Git 工作树部署多个 AI 编程 Agent 时,人们通常会假设它们是完全独立的。虽然工作树提供了独立的文件系统、工作目录和 HEAD 指针,但它们共享同一个底层的对象数据库和分支命名空间。这种共享架构在多个 Agent 并发执行 Git 命令时,会引入一些隐蔽的故障模式。理解这些共享状态的风险,有助于防止自动化工作流中出现意外的引用(ref)损坏和静默失败。

The Shared Ref Layer and Mutable State

共享引用层与可变状态

The core problem stems from how Git structures worktrees. Although each worktree maintains its own checked-out files and staging index, all worktrees in a repository point to the same .git directory. The object database, reflogs, and branch references are globally mutable across the entire repository. When one agent executes a destructive command like git reset --hard or git branch -D, the mutation immediately propagates to the shared object store. Sibling worktrees referencing those same commits or branches observe the change instantly, which can break active diffing, rebasing, or logging operations.

核心问题源于 Git 构建工作树的方式。尽管每个工作树都维护着各自的检出文件和暂存索引,但仓库中的所有工作树都指向同一个 .git 目录。对象数据库、引用日志(reflogs)和分支引用在整个仓库范围内都是全局可变的。当一个 Agent 执行诸如 git reset --hard 或 git branch -D 之类的破坏性命令时,这种变更会立即传播到共享的对象存储中。引用相同提交或分支的兄弟工作树会瞬间感知到这一变化,这可能会导致正在进行的差异比较(diffing)、变基(rebasing)或日志记录操作中断。

Consider a scenario where Agent A and Agent B are spawned in parallel. If Agent A performs a destructive force reset on a shared tracking branch, Agent B can experience sudden ref invalidation. The following table outlines the primary failure taxonomy, their triggers, their blast radius, and their corresponding defensive patterns.

考虑一个 Agent A 和 Agent B 并行启动的场景。如果 Agent A 对共享的跟踪分支执行了破坏性的强制重置,Agent B 可能会遭遇突发的引用失效。下表概述了主要的故障分类、触发条件、影响范围及其相应的防御模式。

Failure ModeTriggerBlast RadiusDefensive Pattern
故障模式触发条件影响范围防御模式
Cross-Worktree Ref Mutationgit reset --hard or git branch -D inside an active worktreeImmediate invalidation of refs in sibling worktreesRestrict agents to non-destructive commands; delegate all ref pruning to the orchestrator
跨工作树引用变更在活跃工作树内执行 git reset --hard 或 git branch -D导致兄弟工作树中的引用立即失效限制 Agent 仅执行非破坏性命令;将所有引用清理工作委托给编排器
Branch Creation RaceConcurrent git worktree add calls attempting to create identical branch namesSilent failure or hard error in the second agent spawnUse orchestrator-assigned unique suffixes or agent-id branch prefixes
分支创建竞争并发调用 git worktree add 尝试创建相同名称的分支第二个 Agent 启动时静默失败或报错使用编排器分配的唯一后缀或 Agent ID 作为分支前缀
Reflog ContaminationFrequent concurrent commits and fast-forwards to the same local branchConfused log histories and difficult rollbacksIsolate working branches strictly per agent instance
引用日志污染频繁并发提交并快进(fast-forward)到同一本地分支日志历史混乱,难以回滚为每个 Agent 实例严格隔离工作分支

Preventing Branch Name Collisions

防止分支名称冲突

Branch name collisions represent another frequent point of failure in automated orchestration. Git prohibits checking out the same branch in more than one worktree simultaneously. If an automation script spawns two agents and both attempt to create or check out agent/fix-login, the second operation fails. Relying on agents to pick their own names or depending solely on static task descriptions often results in race conditions. To eliminate this collision window at the naming layer, branch creation must be owned by the orchestrator prior to spawning the agent. Injecting a short unique suffix into the branch name ensures uniqueness without sacrificing readability.

分支名称冲突是自动化编排中另一个常见的故障点。Git 禁止在多个工作树中同时检出同一个分支。如果自动化脚本启动了两个 Agent,且两者都尝试创建或检出 agent/fix-login,那么第二个操作就会失败。依赖 Agent 自行选择名称,或仅依赖静态的任务描述,往往会导致竞争条件。为了在命名层消除这种冲突窗口,分支创建必须在启动 Agent 之前由编排器完成。在分支名称中注入一个简短的唯一后缀,既能确保唯一性,又不会牺牲可读性。

#!/usr/bin/env bash
set -euo pipefail

TASK_NAME="fix-login"
UNIQUE_SUFFIX="a7b3"
BRANCH_NAME="agent/${TASK_NAME}-${UNIQUE_SUFFIX}"
WORKTREE_PATH=".worktrees/${TASK_NAME}-${UNIQUE_SUFFIX}"

git branch "${BRANCH_NAME}" main
git worktree add "${WORKTREE_PATH}" "${BRANCH_NAME}"

echo "Spawned agent in worktree at ${WORKTREE_PATH} on branch ${BRANCH_NAME}"

This script demonstrates how an orchestrator can provision an isolated worktree with a collision-safe branch name before handing execution over to an agent process. By preventing agents from executing branch creation or deletion commands directly, the repository maintains structural integrity.

该脚本演示了编排器如何在将执行权移交给 Agent 进程之前,预先配置一个带有防冲突分支名称的隔离工作树。通过禁止 Agent 直接执行分支创建或删除命令,仓库能够保持结构完整性。

Securing Multi-Agent Workflows

保障多 Agent 工作流的安全

Managing shared Git state effectively requires treating the object database as a global resource that only a centralized orchestrator should modify. Agents should be constrained to local commits within their assigned branch. Once an agent completes its task, the orchestrator verifies the changes, merges the results, and handles branch deletion during the cleanup phase. Adopting this defensive lifecycle prevents race conditions and ensures that parallel workflows scale reliably without stepping on each other’s refs.

有效管理共享的 Git 状态,需要将对象数据库视为一种全局资源,仅允许中心化的编排器对其进行修改。Agent 应被限制在其分配的分支内进行本地提交。一旦 Agent 完成任务,编排器将验证更改、合并结果,并在清理阶段处理分支删除。采用这种防御性的生命周期管理,可以防止竞争条件,并确保并行工作流能够可靠地扩展,而不会相互干扰彼此的引用。