DeltaDB 把版本控制推进到 commit 之间:每次编辑都成为可追溯历史

2026-08-06 43 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

Git 擅长保存开发者主动确认的项目状态,却不会解释一个 commit 是怎样形成的。Zed 编辑器团队发布的 DeltaDB 将视线移到这段空白区域:持续记录两次 commit 之间的编辑操作,让代码的形成过程也成为可以查询和恢复的历史。目前项目仍处于 Early Access 阶段,适合关注和试验,但还不宜未经验证就承担关键仓库的唯一恢复职责。

Git 保存结果,DeltaDB 关注过程

一次看似简单的提交,背后可能经历多轮试探:重命名接口、拆分函数、删除失败实现、恢复旧逻辑,再补上测试。Git 最终通常只看到暂存区中的快照。

git add src tests
git commit -m "refactor parser error handling"

这个 commit 能说明最终有哪些文件发生变化,却很难回答下面的问题:

  • 某段后来被删除的实现具体写过什么?
  • 重构过程中,错误是在哪一次编辑后出现的?
  • 开发者如何从最初方案逐步收敛到当前结构?
  • 尚未 commit、stash,甚至还没保存多久的工作能否恢复?

DeltaDB 所强调的“Software is made between commits”,正是在区分“最终版本”和“创作轨迹”。它不是简单要求开发者增加 commit 频率,而是试图降低记录过程的操作成本:编辑本身就是事件,不必等开发者停下来整理提交。

操作历史能解决什么

细粒度历史最直接的价值是恢复。传统撤销栈通常依赖当前编辑器会话;Git 则要求变化已经进入 commit 或 stash。位于两者之间的持续记录,可以覆盖关闭窗口、跨会话回看以及恢复局部尝试等场景。

它也可能改善调试。假设测试在半小时内从通过变成失败,而工作区积累了大量未提交变化。只有最终 diff 时,开发者需要手工拆分修改;如果可以按编辑时间回放,就能更快缩小引入问题的操作范围。

不过,来源摘要并未给出 DeltaDB 的存储格式、查询接口、编辑器外集成方式或性能模型。因此,不应把上述场景理解成已经确认的具体 API。更准确的判断是:DeltaDB 提供了一种比 commit 更细的版本控制方向,其实际能力仍需结合 Early Access 版本验证。

可以这样实践:做一个最小编辑日志

在正式试用 DeltaDB 前,可以用一个小型实验理解这种模型。下面的 Python 脚本只使用标准库,每秒检查指定文本文件;一旦内容变化,就把时间、内容哈希和 unified diff 写入 JSON Lines 日志。

这不是 DeltaDB 的实现,也不代表它的内部格式,只是一个可运行的概念验证。将脚本保存为 edit_journal.py,然后把命令中的 demo.txt 换成要观察的文件。

#!/usr/bin/env python3
import argparse
import difflib
import hashlib
import json
import time
from datetime import datetime, timezone
from pathlib import Path


def read_text(path: Path) -> str:
    try:
        return path.read_text(encoding="utf-8")
    except FileNotFoundError:
        return ""


def digest(content: str) -> str:
    return hashlib.sha256(content.encode("utf-8")).hexdigest()


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("file", type=Path)
    parser.add_argument("--log", type=Path, default=Path(".edit-journal.jsonl"))
    parser.add_argument("--interval", type=float, default=1.0)
    args = parser.parse_args()

    previous = read_text(args.file)
    print(f"Watching {args.file}; writing events to {args.log}")

    try:
        while True:
            time.sleep(args.interval)
            current = read_text(args.file)
            if current == previous:
                continue

            diff = "".join(difflib.unified_diff(
                previous.splitlines(keepends=True),
                current.splitlines(keepends=True),
                fromfile=f"{args.file}:before",
                tofile=f"{args.file}:after",
            ))
            event = {
                "recorded_at": datetime.now(timezone.utc).isoformat(),
                "file": str(args.file),
                "sha256": digest(current),
                "diff": diff,
            }
            with args.log.open("a", encoding="utf-8") as log:
                log.write(json.dumps(event, ensure_ascii=False) + "\n")

            print(event["recorded_at"], event["sha256"][:12])
            previous = current
    except KeyboardInterrupt:
        print("Stopped")


if __name__ == "__main__":
    main()

运行方式如下:

touch demo.txt
python3 edit_journal.py demo.txt

在另一个终端修改文件,再查看记录:

printf 'def total(values):\n    return sum(values)\n' > demo.txt
printf '\nprint(total([1, 2, 3]))\n' >> demo.txt
python3 -m json.tool --json-lines .edit-journal.jsonl

这个实验很快会暴露真实系统必须处理的问题:原子保存可能产生临时文件,大型文件的完整 diff 成本较高,重命名需要身份追踪,二进制内容不能直接按文本比较,日志本身还可能记录密钥或个人数据。产品级实现需要在完整性、性能、压缩和隐私之间做出明确选择。

引入团队前要检查的边界

DeltaDB 与 Git 更可能是互补关系,而不是替代关系。Git commit 仍然承担代码评审、分支协作、发布标记和远程同步等稳定职责;操作级历史则服务于个人恢复、过程回放和细粒度诊断。

评估 Early Access 版本时,可以重点检查:

  • 数据保存在本机还是会同步到远端,团队能否控制保留期限。
  • .env、私钥、访问令牌和受监管数据是否能够排除或清理。
  • 大型仓库、生成文件和频繁格式化场景下,CPU、磁盘与延迟开销是否可接受。
  • 编辑器崩溃、文件重命名、分支切换和 Git rebase 后,历史是否仍然连贯。
  • 能否导出、搜索和恢复单个文件或选定操作,而不只是整体回滚。

更稳妥的采用路径是从非敏感仓库开始,把 DeltaDB 当作附加历史层,同时保留正常的 commit、远端推送和备份流程。只有当数据边界、恢复能力与资源开销都经过验证后,再扩大使用范围。细粒度版本控制确实补上了 Git 长期忽略的一段历史,但记录得越完整,隐私和存储治理就越不能被当成附带问题。


相关推荐