代码是怎么写出来的?Git 只记录了结果,从来不记录过程。每一次 git commit 都是一个快照——代码在某个时刻的样子,至于为什么变成这样、经历了什么讨论、推翻了什么方案,Git 一概不知。Zed 团队觉得这个假设有问题,他们正在开发一个叫 DeltaDB 的新版本控制系统,核心主张是:代码变更应该与产生这段变更的对话绑定在一起。
Git 的盲区:只有快照,没有故事
Git 的数据模型本质是一棵对象树:blob 存文件内容,tree 存目录结构,commit 存快照引用加上一段自由格式的 message。这个模型极其擅长回答"代码现在是什么样",但对"代码为什么变成这样"几乎无能为力。
实际开发中,一段代码的诞生往往伴随着大量对话:PR review 里的争论、Slack 上的权衡、设计文档里的取舍。这些对话才是代码真正的"来源",但它们散落在不同工具里,和 Git commit 之间只有一条脆弱的关联——commit message 里手动写个链接,或者 PR description 里贴个引用。
更具体的问题包括:
- commit message 是事后补写的叙事,不是实时对话的忠实记录。开发者经常在写完代码后才"编"一段 message,信息损失不可避免。
- merge 和 rebase 会破坏时间线。一次 squash merge 把十次提交压缩成一条,中间的讨论脉络被抹平。
- diff 是静态对比,看不出"为什么删了这行"——也许是因为一次 code review 指出了性能问题,也许只是重构顺手清理。原因在对话里,不在 diff 里。
DeltaDB 的核心模型:变更 = 操作 + 对话
DeltaDB 想把版本控制的基本单位从"快照"换成"操作"(operation)。每个操作不仅记录代码发生了什么变化,还绑定产生这段变化的对话上下文。
可以这样理解两者的区别:
Git: commit → { tree snapshot, author, message }
DeltaDB: operation → { change, conversation_context, author }
在 DeltaDB 的模型里,"对话"不是可选的附件,而是变更记录的一部分。这意味着:
- 追溯动机变得直接——看一个操作,就能看到当时的讨论,不需要去翻 PR 或聊天记录。
- 操作序列本身就是历史——不需要靠 commit 铴来重建时间线,操作流天然按时间排列。
- 协作冲突可以在对话层面解决——两个人对同一段代码有不同修改,背后往往是不同观点的碰撞,DeltaDB 让这些观点可见。
用一个伪项目感受差异
DeltaDB 还在早期开发阶段,没有可用的 CLI 或 SDK。但我们可以用一个最小化的 JSON 结构来模拟它的操作记录格式,理解它和 Git commit 的本质区别。
先看 Git 的世界——一个典型的 commit:
# Git:只记录快照和自由文本
git log --format='{ "hash": "%H", "message": "%s", "author": "%an" }' -1
# 输出类似:
# { "hash": "a1b2c3d4", "message": "fix: handle null in parser", "author": "zhangsan" }
commit message 里写了一句"fix: handle null in parser",但 null 是怎么发现的、讨论了哪些方案、为什么选了当前实现——全靠读者猜。
下面用一个脚本模拟 DeltaDB 风格的操作记录,把对话上下文和代码变更绑定在一起:
#!/usr/bin/env python3
"""模拟 DeltaDB 风格的操作记录——变更与对话绑定"""
import json
from datetime import datetime, timezone
# 一个 DeltaDB 风格的 operation 记录
operation = {
"id": "op_7f3a2b",
"timestamp": datetime.now(timezone.utc).isoformat(),
"author": "zhangsan",
# 代码变更:精确定位到具体操作,而非整个 tree 快照
"change": {
"file": "src/parser.py",
"action": "insert",
"line_range": [42, 44],
"content": "if token is None:\n return fallback()\n",
"replaces": "if token:\n return fallback()\n",
},
# 对话上下文:这段代码为什么这样改
"conversation_context": {
"source": "code_review",
"thread_id": "pr_234_review_thread_5",
"summary": "李四在 review 中指出 parser 对 None token 的处理会抛 AttributeError,建议加显式检查",
"decisions": [
"选择 fallback() 而非 raise,因为上游调用方不期望异常",
"不修改 token 生成逻辑,因为 None 在某些边界输入下是合法中间状态",
],
"alternatives_considered": [
"在 token 生成阶段过滤 None → 影响下游三个模块,改动范围过大",
"raise ParserError → 与项目错误处理策略不一致",
],
},
}
# 写入操作日志(模拟 DeltaDB 的存储方式)
with open("operations_log.jsonl", "a") as f:
f.write(json.dumps(operation, ensure_ascii=False) + "\n")
print(f"操作已记录: {operation['id']}")
print(f"变更: {operation['change']['file']} L{operation['change']['line_range']}")
print(f"动机: {operation['conversation_context']['summary']}")
运行这个脚本后,operations_log.jsonl 里每行就是一个完整的"变更+对话"记录。对比 Git commit,关键差异一目了然:
- Git commit 存的是整个项目的 tree 快照 + 一段手动写的 message。
- DeltaDB operation 存的是精确的代码操作 + 结构化的对话上下文。
如果要追溯"为什么 parser 里加了 if token is None",在 Git 里你得翻 PR、翻聊天记录、翻设计文档;在 DeltaDB 的模型里,这条信息直接就在操作记录里。
这不是换个存储格式,是换一种理解代码的方式
DeltaDB 的野心不只是"给 commit 加个对话字段"。它想改变的是版本控制的基本认知框架:
- 从"代码是什么"到"代码怎么来的"。Git 回答前者,DeltaDB 想同时回答后者。
- 从"快照对比"到"操作流"。快照是静态的,操作流是动态的——你可以看到代码一步步演化的过程,而不只是起点和终点的差异。
- 从"事后叙事"到"实时记录"。对话发生在写代码的同时,而不是写完代码之后补一段 message。
这些变化对日常开发的影响可能很深:
- Code review 不再是外部流程,而是版本控制的一部分——review 里的讨论直接成为操作记录的上下文。
- 回滚不只是撤销代码,还可以看到撤销的决策依据——"当时为什么这样改,后来为什么又改回来了"。
- 新人理解代码的成本降低——不需要靠口口相传的"项目传说"来理解历史决策,操作记录里就有。
现实挑战与冷静判断
DeltaDB 的理念很有吸引力,但落地面临几个硬问题:
-
对话的结构化存储很难。代码变更可以精确描述,但对话天然是混乱的——闲聊、吐槽、正式讨论混在一起,哪些该记录、怎么摘要、谁来做摘要,都是未解问题。
-
与现有生态的兼容性。Git 不是版本控制,Git 是整个开发基础设施——CI/CD、GitHub/GitLab、包管理、部署脚本全部围着 Git 转。DeltaDB 要么提供 Git 兼容层,要么重建整套工具链,后者几乎不可能短期完成。
-
隐私和噪音。不是所有对话都应该被永久记录到版本控制里——有些讨论涉及敏感信息,有些只是无关的闲聊。过滤机制必不可少,但过滤本身又会引入信息损失。
-
操作流的合并冲突。Git 的 merge 冲突已经是开发者的日常痛苦,操作流的冲突可能更复杂——不只是代码冲突,还有对话上下文的冲突、决策逻辑的冲突。
什么时候值得关注
DeltaDB 目前还在早期实验阶段,没有发布可用版本。但它提出的问题值得每个团队现在就思考:
- 你的团队里,代码变更的"动机"信息散落在哪里?能追溯吗?
- PR review 的讨论有没有和 commit 建立可靠关联?还是只靠手动贴链接?
- 新人理解历史决策的成本有多高?
如果这些问题让你觉得痛,可以现在就做一些低成本改进:
# 低成本实践:用 Git trailer 把 PR 链接写进 commit message
git commit -m "fix: handle null in parser" \
-m "Reviewed-on: https://github.com/org/repo/pull/234" \
-m "Decision: use fallback() per review thread #5"
# 用 git log 查看时 trailer 会自动显示
git log --format=fuller
这不是 DeltaDB,但它让 Git commit 和对话之间有了比"手动贴链接"更结构化的关联。在 DeltaDB 成熟之前,这是可行的中间路线。
版本控制的基本假设被挑战了——代码的来源不是快照,而是对话。DeltaDB 能走多远取决于它能不能解决对话结构化存储和生态兼容这两个硬骨头。但无论 DeltaDB 最终成败,它提出的问题本身已经值得认真对待:你的版本控制系统,到底在记录什么?