Gas Town 集成分支(Integration Branches)实战指南:让 Epic 级工作作为一个整体落地 main
Gas Town 集成分支Integration Branches实战指南让 Epic 级工作作为一个整体落地 main【免费下载链接】gastownGas Town - multi-agent workspace manager项目地址: https://gitcode.com/GitHub_Trending/ga/gastown集成分支Integration Branch是 Gas Town 多智能体工作区中支撑 Epic 级工作流的端到端机制为某个 Epic 创建共享分支后它自动成为管线中每一个环节的目标——Polecat 从该分支派生出工作树从而天然包含已完成兄弟任务的成果、Refinery 将完成的 MR 合入集成分支而非 main、当 Epic 的所有子任务关闭后Refinery 可将集成分支作为单一合并提交落回其基础分支默认是 main也可在创建时用--base-branch指定。读完本文你将掌握集成分支的完整生命周期、自动检测原理、命名模板、三个 CLI 命令、配置开关、自动落地Auto-Land以及三层安全护栏能够在自己的 Rig 上让整个 Epic「从第一次 sling 到最终落地」以一致单元的形式流过系统全程无需手工指定分支目标。为什么要用集成分支分片落地的困境没有集成分支时Epic 的工作是零散落地的Child A ──► MR ──► main (周二落地) Child B ──► MR ──► main (周三落地破坏了 A 的工作) Child C ──► MR ──► main (周四落地依赖 AB 同时成立)每个子任务独立合入 main。如果子任务 C 依赖 A 和 B 的成果彼此协调一致那么你只能赌合并顺序并祈祷两次落地之间不出问题——这正是跨子任务依赖Cross-child deps风险最高的场景。集成分支的解法是把 Epic 的工作批量汇聚到一条共享分支上再一次性原子化落地Epic: gt-auth-epic │ ┌─────────────┼─────────────┐ │ │ │ Child A Child B Child C │ │ │ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌────────┐ │ MR A │ │ MR B │ │ MR C │ └───┬────┘ └───┬────┘ └───┬────┘ │ │ │ └───────────┼───────────┘ ▼ integration/gt-auth-epic (共享分支) │ ▼ gt mq integration land base branch (main 或 --base-branch) (单一合并提交)所有子 MR 先合入集成分支子任务可以建立在彼此的成果之上一切就绪后一条命令全部落地。有 / 无集成分支对比方面无集成分支有集成分支MR 目标mainintegration/{epic}落地时机每个 MR 独立落地所有 MR 一起落地跨子任务依赖有风险——取决于合并顺序安全——子任务共享分支回滚逐个 revert 提交revert 一个合并提交main 上的 CI每个 MR 各跑一次合并后的整体跑一次完整工作流从建 Epic 到最终落地以文档中的「Auth overhaul」示例为主线走一遍九个步骤1. 创建 Epic 及其子任务。将工作组织成一个 Epic下面挂子任务或子 Epic并在子任务之间建立依赖关系定义哪些可以并行、哪些必须等待。2. 创建集成分支。这是所有子工作汇集的共享分支gt mq integration create gt-auth-epic3. 创建 convoy 跟踪工作。Convoy 为整个 Epic 的进度提供一个仪表盘gt convoy create Auth overhaul gt-auth-tokens gt-auth-sessions gt-auth-middleware4. Sling 第一波任务。找出没有阻塞的子任务并 sling 到 Rig。由于跟踪用的 convoy 已经存在使用--no-convoygt sling gt-auth-tokens gastown --no-convoy gt sling gt-auth-sessions gastown --no-convoy5. Polecat 处理工作。每个 Polecat 从集成分支派生工作树因此启动时就带有已落地的兄弟任务成果完成后提交合并请求。6. Refinery 合入集成分支。Refinery 不把 MR 合到 main而是合入集成分支并将子任务标记为完成。7. 通过 convoy 跟踪进度。每次 Refinery 完成一个任务convoy 状态都会更新gt convoy status hq-cv-abc8. Sling 下一波任务。当一波完成、依赖的子任务解除阻塞后sling 下一批。这些 Polecat 会从集成分支启动——此时该分支已包含前一波的全部成果gt sling gt-auth-middleware gastown --no-convoy9. 完成后落地。当 Epic 下所有子任务关闭后集成分支即可落地。若启用了integration_branch_auto_landRefinery 会在 patrol 时自动执行否则手动落地gt mq integration land gt-auth-epic该命令将集成分支以单一合并提交的方式合回基础分支默认 main删除分支并关闭 Epic。生命周期源码级拆解1. 创建 Epicbd create --typeepic --titleAuth overhaul # → gt-auth-epic然后在 Epic 下按正常方式创建子 issue。2. 创建集成分支gt mq integration create gt-auth-epic # → Created integration/gt-auth-epic from origin/main # → Stored branch name in epic metadata这条命令把新分支推送到 origin并把分支名记录到 Epic 元数据中。从源码看runMqIntegrationCreateinternal/cmd/mq_integration.go依次执行验证 Epic 存在且Type epic→ 检查是否已有integration_branch元数据有则报错除非--force→ 用模板生成分支名 → 校验分支名 → 用resolveUniqueBranchName消除重名 →git fetch origin→ 从基础分支默认 Rig 的default_branch创建本地分支 → push 到 origin → 把分支名与基础分支写入 Epic 描述。值得注意的两个细节元数据即真相分支名通过AddIntegrationBranchField写入 Epic 描述中的integration_branch: name行实现见 internal/beads/integration.go 的addMetadataFieldland/status在解析时优先读取该字段而不是重新套用模板。分支名校验严格validateBranchName使用正则[~^:\s\\?*\[]|\.\.|\{拒绝非法字符并检查 200 字符上限为 GitHub 的refs/heads/后 244 字节限制留出余量、.lock后缀、首尾斜杠/点、连续斜杠等。3. Sling 工作像正常一样给 Polecat 分配子任务gt sling gt-auth-tokens gastown gt sling gt-auth-sessions gastown当 issue 是有集成分支的 Epic 的子任务时Polecat 自动检测集成分支无需手工指定目标。4. MR 合入集成分支Polecat 运行gt done或gt mq submit时自动检测生效gt done → 检测到父 Epic gt-auth-epic → 找到 integration/gt-auth-epic 分支 → 提交指向 integration/gt-auth-epic 的 MR而非 mainRefinery 处理这些 MR 并合入集成分支。核心检测逻辑在 internal/beads/integration.go 的DetectIntegrationBranch沿 parent 链向上最多 10 层maxDepth 10遇到Type epic的节点时先读integration_branch:元数据为空则退回BuildIntegrationBranchName按命名规范生成然后先查远程分支远程是权威本地 ref 可能因未 prune 而陈旧远程失败再回退本地若{title}模板匹配不到真实分支还会尝试旧版integration/{epic}模板以兼容历史分支。5. 全部完成时落地一旦所有子任务关闭、所有 MR 合入gt mq integration land gt-auth-epic # → Verified all MRs merged # → Merged integration/gt-auth-epic → base branch (--no-ff) # → Tests passed # → Pushed to origin # → Deleted integration/gt-auth-epic # → Closed epic gt-auth-epic自动检测机制集成分支无需手工指定目标三个系统自动检测系统作用配置开关gt done/gt mq submitMR 指向集成分支而非 mainintegration_branch_refinery_enabledPolecat 派生工作树从集成分支派生integration_branch_polecat_enabledRefinery patrol检查集成分支是否可落地integration_branch_auto_land检测算法gt done或gt mq submit运行时步骤动作结果1加载配置检查integration_branch_refinery_enabled为 false 则跳过检测2从分支名获取当前 issue ID例如gt-auth-tokens3沿 parent 链向上遍历最多 10 层找到祖先 Epic4对每个 Epic从元数据读取integration_branch:获取存储的分支名5回退按模板生成名称例如integration/{title}6检查分支是否存在先本地后远程验证其真实存在7找到则把 MR 指向该分支而非 maingt mq submit的--epic标志可绕过自动检测直接按配置模板解析目标分支默认integration/{epic}。这是文档明确记录的例外路径——例如在gt mq integration create成功后的提示信息中也直接建议gt mq submit --epic epic-id。分支命名模板变量变量说明示例{title}清洗后的 Epic 标题小写、连字符化、最长 60 字符add-user-authentication{epic}完整 Epic IDRA-123{prefix}Epic ID 首个连字符之前的前缀RA{user}Git user.nameklauern{title}的清洗规则在 internal/beads/integration.go 的SanitizeBranchSegment中实现转小写 → 非字母数字转连字符 → 折叠连续连字符 → 去除首尾连字符 → 截断到 60 字符。若清洗结果为空标题缺失或全是特殊字符会回退使用 Epic ID避免产生integration/这类非法分支名。优先级优先级来源示例1最高create 时的--branch标志--branch feat/{epic}2配置中的integration_branch_template{user}/{epic}3最低默认integration/{title}这一优先级在 internal/cmd/mq_integration.go 的getIntegrationBranchTemplate中落地CLI 覆盖 Rig settings 中的IntegrationBranchTemplate 默认常量integration/{title}。示例# 默认模板使用 Epic 标题 gt mq integration create gt-auth-epic # → integration/add-user-authentication (来自 Epic 标题) # 配置自定义模板: {user}/{prefix}/{epic} gt mq integration create RA-123 # → klauern/RA/RA-123 # 用 --branch 标志覆盖 gt mq integration create RA-123 --branch feature/{epic} # → feature/RA-123实际创建的分支名存储在 Epic 元数据中因此无论使用哪个模板自动检测总能找到正确分支。重名消歧若两个 Epic 生成相同分支名如标题相同会自动追加 Epic ID 的数字后缀如integration/add-auth-456。该逻辑在resolveUniqueBranchName中实现先检查本地与origin/上是否已存在同名分支存在则追加extractEpicNumericSuffix提取的最后一段数字后缀若两个名字都被占用则报错要求用--branch显式指定。命令参考gt mq integration create epic-id为 Epic 创建集成分支。gt mq integration create epic-id [flags]Flags:Flag说明默认--branch覆盖分支名模板配置模板或integration/{title}--base-branch从该分支创建同时决定land合回哪里origin/default_branch执行步骤验证 Epic 存在按模板生成分支名展开变量校验分支名git 安全字符从 base 创建本地分支push 到 origin将分支名与基础分支存入 Epic 元数据错误场景Epic 不存在分支已存在生成的分支名含非法字符从源码看创建成功后还会打印一行提示若分支名不在integration/前缀下会警告该分支不受 pre-push 钩子护栏保护详见「安全护栏」一节。gt mq integration status epic-id显示 Epic 的集成分支状态。gt mq integration status epic-id [flags]Flags:Flag说明--json以 JSON 输出输出包含分支名与创建日期领先 main 的提交数已合入的 MRclosed指向集成分支待处理的 MRopen指向集成分支子 issue 进度已关闭 / 总数是否可落地ready-to-land自动落地配置可落地Ready-to-land标准需全部满足集成分支有领先 main 的提交Epic 有子任务所有子任务已关闭无待处理 MR所有已提交工作均已合入runMqIntegrationStatus在源码中正是按此计算CommitsAhead对比origin/base与集成分支、bd.List统计子任务 closed/total、按 MR 的 target 字段过滤 merged/pending最后isReadyToLand四条件与运算--json输出结构见IntegrationStatusOutputinternal/cmd/mq_integration.go。gt mq integration land epic-id将 Epic 的集成分支合回其基础分支。gt mq integration land epic-id [flags]Flags:Flag说明默认--force即使仍有 MR 打开也落地false--skip-tests合并后跳过测试false--dry-run仅预览不做任何改动false执行步骤验证 Epic 存在且有集成分支从 Epic 元数据读取基础分支未存储则回退到 Rig 的default_branch检查所有指向集成分支的 MR 是否已合入fetch 最新 refs 并做幂等检查若已合并则直接跳到清理获取文件锁防止并发落地竞争创建临时 worktree避免打扰运行中的 Agent用--no-ff把集成分支合到基础分支运行测试除非--skip-tests验证合并确实带来了变更防止空合并push 到 origin删除集成分支本地与远程关闭 Epic幂等重试若落地在 push 之后、清理删分支/关 Epic之前崩溃重跑同一命令是安全的。幂等检查检测到集成分支已是目标分支的祖先会直接跳到清理阶段。错误场景Epic 没有集成分支存在待处理 MR可用--force覆盖测试失败空合并没有可落地的变更源码级实现细节runMqIntegrationLandinternal/cmd/mq_integration.go在文档描述的基础上还有几个值得注意的实现点隔离的落地 worktreecreateLandWorktree使用flock在rig/.runtime/locks/land-worktree.lock上加全局文件锁并在rig/.land-worktree中从.repo.gitbare repo创建工作树避免 checkout/merge 破坏 refinery/mayor 的工作树。注释明确指出单 Rig 内所有落地操作即使指向不同目标分支共享同一把锁这是有意为之——固定路径复用 单 Rig 简单性优先于并行落地。空合并防护合并后执行git diff --stat HEAD~1..HEAD若无任何文件变更说明冲突解决把集成分支工作全部丢弃了会拒绝继续并保留分支提示人工用git diff target...origin/branch检查。结构化冲突错误合并冲突时先捕获冲突文件列表再 abort 合并输出LAND_FAILED: epic... branch... target... reasonconflict files...标记行并返回LandConflictError类型错误Unwrap支持errors.As判断。Refinery patrol 公式会 grep 该标记驱动恢复路径。清理顺序刻意设计先关 Epic 再删分支——若删分支后崩溃会留下不可重试状态没有分支可供幂等重跑先关 Epic 则操作始终处于可重试状态。配置默认分支Default BranchRig 的default_branch在config.json中设置gt rig add时自动检测控制无集成分支时工作合入哪里也是创建集成分支时的默认基础分支。如果你的项目用develop或master而非main在 rig config 中设置一次整条管线都会跟随{ type: rig, name: myproject, default_branch: develop }对应配置类型见 internal/config/types.go 中的RigConfig。集成分支设置所有集成分支字段位于 Rig settingssettings/config.json的merge_queue下{ merge_queue: { enabled: true, integration_branch_polecat_enabled: true, integration_branch_refinery_enabled: true, integration_branch_template: integration/{title}, integration_branch_auto_land: false } }字段类型默认说明integration_branch_polecat_enabled*booltruePolecat 自动从集成分支派生工作树integration_branch_refinery_enabled*booltruegt mq submit与gt done自动检测集成分支作为 MR 目标integration_branch_templatestringintegration/{title}分支名模板支持{title}、{epic}、{prefix}、{user}integration_branch_auto_land*boolfalseRefinery patrol 在所有子任务关闭后自动落地注意*bool字段使用指针语义——null/省略表示「使用默认值」polecat/refinery enabled 为 trueauto-land 为 false。显式设为false才表示禁用。对应 Go 类型为MergeQueueConfiginternal/config/types.go。自动落地Auto-Landing当integration_branch_auto_land为true时Refinery patrol 会自动落地可落地的集成分支。工作方式每个 patrol 周期Refinery列出所有打开的 Epicbd list --typeepic --statusopen检查每个 Epic 的集成分支gt mq integration status epic-id若ready_to_land: true执行gt mq integration land epic-id若未就绪跳过Epic 工作未完成这在 refinery patrol 公式internal/formula/formulas/mol-refinery-patrol.formula.toml的check-integration-branches步骤中逐条落地先读integration_branch_refinery_enabled与integration_branch_auto_land两个变量任一为 false 即提前退出auto_landfalse时还明确 FORBIDDEN 使用裸 git 命令手工落地。自动落地的条件两个配置开关必须同时为 trueintegration_branch_refinery_enabled: true集成分支功能开启integration_branch_auto_land: true自动落地开启任一为 falsepatrol 步骤提前退出。落地失败的恢复路径公式对gt mq integration land的非零退出码有强制处理流程文档原版未展开来自 mol-refinery-patrol.formula.toml首先防御性清理.land-worktree残留然后按LAND_FAILED:标记分类失败——reasonconflict时创建冲突解决任务并阻塞该 Epicreasonmerge-error等基础设施/瞬时错误时走重试路径无标记的前置条件失败如仍有打开 MR / 打开子任务则记录消息并升级到 Mayor且本轮不重试同一 Epic。核心原则是Refinery 绝不把整合过程留在不可观察状态静默跳过会导致集成分支成为孤儿、永久卡死合并队列。何时启用场景建议信任 CI、无需人工评审启用自动落地落地前需要人工签字保持禁用默认手动落地两者混合保持禁用用gt mq integration land手动控制安全护栏三层防御集成分支落地受三层防御保护第一层公式与角色指令Refinery 公式和角色模板明确禁止用裸 git 命令落地集成分支只授权gt mq integration land。公式中的 FORBIDDEN 部分原文如此「Landing integration branches to the default branch via raw git commands (git merge,git push). Integration branches may ONLY be landed viagt mq integration land epic-id」。该约束同时覆盖自定义模板场景——pre-push 钩子只匹配integration/前缀自定义模板产生的分支要靠这一层语言约束兜底。第二层Pre-Push 钩子.githooks/pre-push钩子检测推送默认分支是否引入了集成分支内容。它使用基于祖先关系的检测若某个origin/integration/*分支 tip 从被推送的提交变为新可达则推送被阻止除非设置GT_INTEGRATION_LAND1。默认分支通过refs/remotes/origin/HEAD动态检测回退main因此不受 Rig 分支命名影响。它能拦截所有合并风格--no-ff、--ff-only、默认合并、rebase只有 cherry-pick产生新 SHA无法检测。适用范围该检查匹配integration/前缀下的分支默认模板。产生integration/之外分支的自定义模板不受钩子覆盖——这种情况由第一层公式语言兜底。前提必须配置core.hooksPath钩子才生效。新 Rig 自动获得存量 Rig 运行gt doctor --fix。第三层授权代码路径gt mq integration land命令使用PushWithEnv()设置GT_INTEGRATION_LAND1让推送通过钩子。任何 Agent 或用户执行裸git push不会设置该变量将被阻止。手动设置环境变量在技术上可行但不属于受支持的工作流——该变量是基于策略的信任边界policy-based trust boundary而非基于能力的安全机制capability-based security mechanism。PushWithEnv实现在 internal/git/git.go与普通Push的唯一区别是用runWithEnvAndTimeout附带额外环境变量。其行为有测试直接佐证internal/git/git_test.gopre-push 钩子中检查GT_INTEGRATION_LAND ! 1即 BLOCKED验证了无变量推送失败、带变量推送成功同文件另一测试还验证了即使设置该变量也无法绕过 fork 默认分支保护RefuseForkBackedDefaultPush。为什么是三层层类型强度局限公式/角色软覆盖所有分支模式AI Agent 可能无视指令Pre-push 钩子硬在 git 边界拦截所有合并风格只匹配integration/*前缀环境变量是策略性的代码路径硬落地命令设置绕过环境变量依赖钩子处于激活状态三层互补公式覆盖自定义模板钩子对默认模板提供硬性执行通过祖先检测拦截合并、快进与 rebase代码路径确保 CLI 命令能绕过钩子。构建管线配置集成分支适配不同的项目工具链。Rig 的构建管线命令会自动注入 polecat-work、refinery-patrol 与 sync-workspace 公式让 Agent 知道如何为每个项目验证工作。五命令管线命令按以下顺序执行任一为空即跳过setup— 安装依赖如pnpm installtypecheck— 静态类型检查如tsc --noEmitlint— 代码风格与质量如eslint .test— 运行测试套件如go test ./...build— 编译/打包如go build ./...配置示例Go 项目默认全为空——按 Rig 单独配置{ merge_queue: { test_command: go test ./..., lint_command: golangci-lint run ./..., build_command: go build ./... } }TypeScript 项目{ merge_queue: { setup_command: pnpm install, typecheck_command: tsc --noEmit, lint_command: eslint ., test_command: pnpm test:unit, build_command: pnpm build } }命令如何流入公式命令从rig/settings/config.json自动注入公式变量Refinery patrolbuildRefineryPatrolVars()在gt prime时读取 rig configPolecat work / syncloadRigCommandVars()在gt sling时读取 rig configgt sling上用户提供的--var标志覆盖 rig config 值。对应公式变量setup_command、typecheck_command、lint_command、test_command、build_command以及run_tests、target_branch等均定义在 mol-refinery-patrol.formula.toml 的[vars]节land 命令中测试的执行则走getTestCommand读取merge_queue.test_commandinternal/cmd/mq_integration.go。runTestCommand用sh -c执行——注释明确这是信任边界test command 来自 operator 控制的 rig config而非 PR 分支或用户输入。空命令 跳过任何留空或未配置的命令被公式静默跳过。这意味着 Go Rig 不需要setup_command或typecheck_command而 TypeScript Rig 可以配置全部五个而不会影响 Go Rig。工作在集成分支上的 Polecat 自动继承 Rig 的构建管线——无需按分支做任何配置。反模式工作开始后才创建集成分支错误先 sling 子任务之后再创建集成分支。在集成分支存在之前 sling 的子任务会指向 main它们的 MR 不会流入集成分支。必须先创建集成分支再 sling 任何子工作。手工指定集成分支目标错误在gt mq submit上使用--branch integration/gt-epic。自动检测会处理这种情况。若发现自己不得不手工指定请检查集成分支是否真的存在integration_branch_refinery_enabled是否不是falseissue 是否是 Epic 的子任务或后代落地部分 Epic错误用--force在子任务仍打开时落地。这违背了集成分支的初衷——它的存在就是为了让工作一起落地。若需要提前落地请先关闭或移除未完成的子任务。参见Polecat Lifecycle — Polecat 如何向合并队列提交Reference — 完整 CLI 参考含 MQ 命令实现与测试gt mq integration三个子命令的完整实现见 internal/cmd/mq_integration.go对应的单元测试见 internal/cmd/mq_integration_test.go覆盖LandConflictError、resolveEpicBranch旧模板回退、validateBranchName、isReadyToLand、模板解析、分支名永不产生非法 ref 等场景自动检测核心算法DetectIntegrationBranch与分支名构建见 internal/beads/integration.goRefinery patrol 公式含 FORBIDDEN 约束、落地失败恢复流程见 internal/formula/formulas/mol-refinery-patrol.formula.toml【免费下载链接】gastownGas Town - multi-agent workspace manager项目地址: https://gitcode.com/GitHub_Trending/ga/gastown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考