news 2026/9/12 16:13:53

bd vc:用 Git 式工作流管理 Beads 问题库的版本控制(commit / merge / status)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
bd vc:用 Git 式工作流管理 Beads 问题库的版本控制(commit / merge / status)

bd vc:用 Git 式工作流管理 Beads 问题库的版本控制(commit / merge / status)

【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads

Beads 是一款为编码 Agent 提供"记忆升级"的数据库工具,它把 issue 数据存放在基于 Dolt 的存储引擎中。bd vc是 Beads 内置的版本控制命令组,让开发者可以用类似 Git 的心智模型——分支、合并、提交、历史——来管理问题数据。读完本文,你将掌握bd vc commitbd vc mergebd vc status三个子命令的完整用法,理解冲突产生的机制与--strategy解决策略的底层原理,并学会用 JSON 输出把版本控制操作接入自动化脚本。

bd vc 是什么:面向问题数据的版本控制命令组

bd vc(Version Control)在命令注册中被归入sync分组(cmd/bd/vc.go),其官方定位是:

Version control operations for the beads database. These commands provide git-like version control for your issue data, including branching, merging, and viewing history.

也就是说,Beads 的问题库本质上是一套拥有完整版本历史的数据库:每次bd createbd edit等写操作都会改变工作集内容,而bd vc负责把这些变更固化成提交、在分支之间合并、并查看当前状态。

需要特别说明的是,Beads 刻意保留了"快捷访问"入口:bd historybd diffbd branch三个命令本身就覆盖了历史查看、差异对比和分支管理,而bd vc则补充了它们没有的操作——commit(提交)与 merge(合并)。如果你的诉求是快速看一眼历史或分支,直接用bd history/bd diff/bd branch(对应文档见 history.md、diff.md、branch.md)更顺手;要做提交与合并,就进入bd vc的子命令体系。

bd vc的基本用法:

bd vc [flags]

其下共三个子命令:bd vc commitbd vc mergebd vc status。三者均不支持 proxied-server 模式(源码中usesProxiedServer()会直接返回 "not supported in proxied-server mode" 错误),因为代理服务器模式下工作集由服务端独占,本地无从谈起提交与合并。

bd vc status:查看分支、提交与未提交变更

bd vc status是最轻量的健康检查命令,用于回答三个问题:当前在哪个分支、HEAD 提交是什么、工作集里有没有未提交的变更。

bd vc status [flags]

运行示例:

bd vc status

其文本输出格式如下(源码见 cmd/bd/vc.go):

📊 Version Control Status Branch: main Commit: a1b2c3d4

从实现看,它依次调用存储层的CurrentBranch(ctx)GetCurrentCommit(ctx):前者在 Dolt 后端走versioncontrolops.CurrentBranch(internal/storage/dolt/store.go),后者读取当前 HEAD 哈希(internal/storage/dolt/versioned.go)。如果读取提交哈希失败,会降级显示(unknown)而不是直接报错,保证了命令的健壮性。

JSON 输出(脚本化)

所有bd vc子命令都支持全局--json标志。status的 JSON 负载包含两个键:

{"branch": "main", "commit": "a1b2c3d4..."}

测试用例(cmd/bd/vc_embedded_test.go)验证了bd vc status --json的分支名必须是main且提交哈希非空——bd init之后仓库默认位于main分支,这一点可以作为脚本断言依据。

bd vc commit:一次性提交全部当前变更

bd vc commit把当前工作集中的所有变更打包成一条新的 Dolt 提交。它等价于一条"全量提交":不需要像 Git 那样先addcommit,写操作产生的所有改动(包括bd create创建的新 issue、bd edit修改的字段等)都会被包含。

bd vc commit [flags]

Flags:

-m, --message string Commit message --stdin Read commit message from stdin

三种提交消息来源

1. 命令行直接指定:

bd vc commit -m "Added new feature issues" bd vc commit --message "Fixed priority on several issues"

2. 从 stdin 读取(支持多行):

echo "Multi-line message" | bd vc commit --stdin

--stdin会读取全部标准输入并去除末尾换行符(strings.TrimRight(string(b), "\n"))。

3. 缺失时的行为:如果既没有-m/--message也没有--stdin,命令直接报错commit message is required (use -m, --message, or --stdin)(测试 cmd/bd/vc_embedded_test.go 专门验证了这一点)。--stdin-m/--message同时指定也会报错:cannot specify both --stdin and -m/--message

空提交的诚实反馈

与 Git 的nothing to commit类似,bd vc commit在干净工作集上不会伪造提交,而是输出:

Nothing to commit

这是由存储层的CommitAll返回值驱动的:DoltStore.CommitAll在底层执行CALL DOLT_COMMIT('-Am', ?, '--author', ?),当捕获到 Dolt 的 "nothing to commit" 错误时返回(false, nil),命令据此判定无需提交(internal/storage/dolt/store.go)。需要注意的是,由于 Beads 的写操作(如bd create)默认自动提交,显式执行bd vc commit时常常已经"无物可提",这是正常现象,两种结果(committed=true/false)都是合法输出。

提交成功后输出新提交哈希的前 8 位:

Created commit a1b2c3d4

JSON 模式下的负载结构为{"committed": bool, "hash": "...", "message": "..."},其中committed=false时 message 固定为"nothing to commit"。测试 cmd/bd/vc_embedded_test.go 验证了--json输出中committed字段必然存在。

并发安全:为什么是"原子信号"而非"比较 HEAD"

值得关注的是CommitAll的设计。早期实现用"提交前后 HEAD 比较"来判断是否真的产生了提交,这在并发写入场景下会把其他进程的提交误记到自己头上。现在的实现让CommitAll返回一个committed bool作为原子信号(见 cmd/bd/vc.go 中的注释,关联缺陷跟踪号 mybd-z9h7j),彻底消除了并发写者误归属的竞态。并发测试 cmd/bd/vc_embedded_test.go 用 10 个 worker 同时bd create+bd vc commit,断言所有 worker 要么成功、要么收到预期的 "one writer at a time" 或 "nothing to commit" 提示,且绝不 panic。

bd vc merge:把分支合并进当前分支

bd vc merge把指定分支合并到当前分支,这是协作场景的核心操作——例如把feature-xyz分支上的 issue 改动合回main

bd vc merge <branch> [flags]

Flags:

--strategy string Conflict resolution strategy: 'ours' or 'theirs'

基础用法

bd vc merge feature-xyz # Merge feature-xyz into current branch bd vc merge feature-xyz --strategy ours # Merge, preferring our changes on conflict bd vc merge feature-xyz --strategy theirs # Merge, preferring their changes on conflict

合并成功时输出Successfully merged feature-xyz;JSON 模式输出{"merged": "feature-xyz", "conflicts": 0}

无冲突合并的底层链路

不带--strategy时,命令调用存储层的store.Merge(ctx, branch)。在 Dolt 后端,这最终执行CALL DOLT_MERGE('--author', ?, ?)(internal/storage/versioncontrolops/version_control.go),即一次裸的 autocommit 模式 DOLT_MERGE。合并成功且无冲突后,Dolt 存储层还会做一件关键收尾:重算is_blocked反规范化列(internal/storage/dolt/store.go)。

这是因为分支合并会引入一批"绕过本地钩子"写入的数据:被合并进来的 issue 的阻塞状态(blocked state)从未经过本分支的钩子计算,直接沿用旧值可能过期。所以Merge在合并前记录 pre-merge HEAD,合并成功后调用recomputeBlockedAfterPull(ctx, preHead),只对自 preHead 以来变化的行重算阻塞状态并提交结果,避免全图重算的开销。这一机制同样适用于后续的冲突解决流程(RecomputeBlockedAfterMerge,见 internal/storage/dolt/store.go)。

冲突发生时的表现

问题数据的合并不可能永远一帆风顺:当两个分支修改了同一条 issue 的同一字段时,冲突就产生了。bd vc merge对冲突的处理分两种情况:

1. 不带--strategy裸 DOLT_MERGE 在 autocommit 下遇到真实冲突会被 Dolt 直接拒绝(Error 1105:"@autocommit must be disabled so that merge conflicts can be resolved ...")。Merge会检测这种冲突形态的错误(通过消息同时包含 "merge conflict" 和 "autocommit" 判定,internal/storage/versioncontrolops/version_control.go),并读取dolt_conflicts表把冲突返回给 CLI。CLI 随后打印冲突字段列表,并给出明确提示:

!! Merge completed with conflicts: - title - priority Resolve conflicts with: bd vc merge feature-xyz --strategy [ours|theirs]

JSON 模式下输出{"merged": "feature-xyz", "conflicts": [冲突字段...]}

2. 带--strategy这是解决冲突的逃生通道。MergeWithStrategy不再走共享连接池的裸合并,而是固定单条连接跑完"合并 → 解析 → 修复 → 提交"整个序列(internal/storage/dolt/store.go)。原因很微妙:Dolt 的冲突容忍会话标志(@@dolt_allow_commit_conflicts@@dolt_force_transaction_commit)是会话级状态,共享连接池可能把后续语句分给另一条连接,导致策略设置失效。固定单连接后,versioncontrolops.MergeWithStrategy才能把ours/theirs真正送达 DOLT_CONFLICTS_RESOLVE。

--strategy的合法值只有两个,存储层做了严格校验(internal/storage/versioncontrolops/conflicts.go):

  • ours:冲突时保留**当前分支(我方)**的修改;
  • theirs:冲突时采用**被合并分支(对方)**的修改。

用策略合并时,即使产生冲突也会完成合并并提交。输出会报告被策略解决的冲突数量:

Merged feature-xyz with 2 conflicts resolved using 'ours' strategy

对应 JSON:{"merged": "feature-xyz", "conflicts": 2, "resolved_with": "ours"}。测试 cmd/bd/vc_embedded_test.go 验证了合并分支后--json输出的merged字段与分支名一致。

注意:策略合并不是万能的

并非所有存储后端都支持--strategy合并。代码在调用MergeWithStrategy前会断言存储层是否实现storage.StrategicMerger接口,不支持时返回错误storage backend %T does not support --strategy merges。此外,--strategy解决的是行级字段冲突,对于**表结构冲突(schema conflict)与约束冲突(constraint violation)**这两类 Dolt 冲突,ours/theirs并不适用——它们没有对应的两方取舍语义,需要另走手工处理路径。

冲突的进阶处理:bd conflicts 命令族

bd vc merge提示里的--strategy只是"整表/整条合并"维度的快刀。当合并因为复杂冲突停摆时,Beads 还提供了专门的bd conflicts命令族(cmd/bd/conflicts.go),它是合并停滞后的运维面:把 Dolt 原始的冲突表变成"按 issue、按字段"的问题导向界面,无需钻进.beads/dolt/<db>目录敲原生 dolt CLI。

核心子命令:

bd conflicts list # 哪些表、哪些 issue 存在冲突 bd conflicts show # 逐字段展示每个冲突行(base/ours/theirs) bd conflicts show bd-1234 # 只看某一条 issue bd conflicts resolve bd-1234 --ours # 保留我方这一条 issue 的修改 bd conflicts resolve --all --theirs # 全部采用对方修改 bd conflicts resolve --conclude # 提交一个已经解析完毕的合并

bd conflicts show会把冲突行按字段三栏展示(base / ours / theirs),且默认只显示发生分歧的字段,--all-fields才显示全部列。bd conflicts resolve支持按 issue 逐行解析bd conflicts resolve bd-1234 --ours)或整表解析--all),只有在所有冲突都清空后才提交合并——部分解析会保留合并打开状态,供下一轮继续。--no-commit可以只解析不提交,--conclude则用来收尾一个"冲突已清零但合并未提交"的中间态。

这一命令族与bd vc merge --strategy共享同一个is_blocked重算钩子(commitMergeResolutionvc merge都调用blockedAfterMergeRecomputerFor定位具体存储实现,cmd/bd/conflicts.go),保证无论走哪条冲突解决路径,合并进来的数据最终都会重算阻塞状态,bd ready不会因过期数据给出错误结果。

自动化友好:JSON 输出约定

三个bd vc子命令都支持全局--json标志,负载键位稳定,适合 CI 与 Agent 脚本消费:

子命令JSON 键说明
bd vc status --jsonbranch/commit当前分支与 HEAD 哈希
bd vc commit --jsoncommitted/hash/messagecommitted=false表示无物可提
bd vc merge --jsonmerged/conflicts/resolved_with无策略时无resolved_with;conflicts 为数字(策略模式)或字段数组(无策略模式)

一个可落地的脚本模式:先bd vc status --json确认分支,再bd vc commit --json -m "..."并检查committed是否为 true,最后bd vc merge <branch> --json检查conflicts是否非零,非零则按需重跑--strategy。注意 proxied-server 模式下三个子命令均不可用,脚本应先行探测运行模式。

测试验证:行为被测试锁定的证据

bd vc的行为有完整的测试覆盖(cmd/bd/vc_embedded_test.go,需BEADS_TEST_EMBEDDED_DOLT=1环境变量启用嵌入式 Dolt 测试):

  • status:断言默认分支为main、提交哈希非空(文本与 JSON 两种模式);
  • commit:覆盖-m提交、--stdin提交、--json负载结构、"干净工作集必须报 nothing to commit"(而不是伪造提交)、缺失消息必须报错;
  • merge:覆盖无冲突合并成功、--jsonmerged字段;
  • 并发:10 个 worker 并发创建 + 提交,验证无 panic、无意外错误,验证CommitAll的原子信号设计。

另有 cmd/bd/vc_test.go 覆盖非嵌入式路径的 CLI 行为。这些测试共同构成了bd vc的契约:提交必须诚实(不伪造空提交)、合并必须报告冲突(不静默吞掉)、并发必须安全(不误归属提交)。

小结:什么时候用什么

  • 快速查看bd history/bd diff/bd branch
  • 固化变更bd vc commit -m "..."(工作集全量提交,空集时诚实报告);
  • 合入分支bd vc merge <branch>(无冲突直接合并;有冲突给字段列表和--strategy提示);
  • 处理停滞的合并bd vc merge <branch> --strategy ours|theirsbd conflicts list/show/resolve命令族;
  • 脚本接入:所有子命令加--json,消费稳定键位。

bd vc的价值在于把数据库级别的版本控制能力以 Git 的心智模型暴露给 Agent 与开发者:分支隔离实验、合并汇聚成果、提交保留可回溯的检查点。其底层以 Dolt 为存储引擎,上层封装了is_blocked重算、冲突策略合并、诚实空提交等大量细节,让"问题数据版本控制"这件事在命令行上保持简洁可信。

【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 16:13:28

kkFileView CAD图纸在线预览实践

kkFileView CAD图纸在线预览实践 【免费下载链接】kkFileView Universal File Online Preview Project based on Spring-Boot 项目地址: https://gitcode.com/GitHub_Trending/kk/kkFileView 当工程团队要在浏览器里评审一张 DWG 图纸时&#xff0c;逐份打开 CAD 客户端…

作者头像 李华
网站建设 2026/9/12 16:13:11

Gemini 3 Pro与GPT-5.2大模型架构与工程实践对比

1. 大模型技术演进现状 2024年大模型技术进入深水区&#xff0c;Gemini 3 Pro与GPT-5.2作为两大技术阵营的代表作&#xff0c;在代码生成、Agent系统和产品级应用三个维度展现出截然不同的技术特性。作为同时使用过两大平台的一线开发者&#xff0c;我将从架构设计、性能表现和…

作者头像 李华
网站建设 2026/9/12 16:12:17

go2rtc 低延迟流媒体:从摄像头到 WebRTC

go2rtc 低延迟流媒体&#xff1a;从摄像头到 WebRTC 【免费下载链接】go2rtc Ultimate camera streaming application 项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc go2rtc 是一个零依赖、跨平台的流媒体应用&#xff0c;能从几十种摄像头协议拉流&#xf…

作者头像 李华
网站建设 2026/9/12 16:10:44

物流成本控制必读:数据分析从Excel到SQL的实战进阶指南

上个月的月度成本复盘会&#xff0c;经理指着投影问了一句&#xff1a;“这个月运输成本环比涨了6.8%&#xff0c;谁能告诉我是涨在哪了&#xff1f;”会议室安静了十几秒。会后我盯着Excel里的运费明细翻到凌晨&#xff0c;最后只能说一句“可能跟油价和旺季有关系”&#xff…

作者头像 李华