Darcs 2.18.5 介绍与选型指南
Darcs 2.18.5 认知篇:Haskell 编写的分布式版本控制系统,patch 交换理论(commutation)、conflictor 与无分支模型,与 Git 2.56.0/Mercurial 7.2.4/Fossil 2.28.0 在性能、学习曲线、生态、许可证维度的量化对比与适用边界(2026-10-27 联网溯源)。
Darcs 2.18.5 介绍与选型指南
目标:讲清 Darcs 是什么、patch(补丁)理论如何决定它的行为边界、与 Git/Mercurial/Fossil 的量化差异,以及在什么场景应该选它、什么场景必须避开它。本篇为认知篇,不包含本地实测,全部事实来自官方渠道联网溯源,查询日期 2026-10-27;安装、配置、命令实操分别见本专栏其余三篇。
一、环境信息
| 项目 | 内容 | 来源(查询日期 2026-10-27) |
|---|---|---|
| 软件 | Darcs(分布式、交互式、智能版本控制系统) | darcs.net 首页 |
| 最新稳定版 | 2.18.5 | darcs.net 首页 “install latest Darcs 2.18.5”;Hackage preferred.json 的 normal-version 首位 |
| 实现语言 | Haskell(GHC 编译) | Hackage darcs.cabal |
| 许可证 | GPL-2.0-or-later | darcs.cabal 中 License: GPL-2.0-or-later |
| 包元数据稳定性标记 | Experimental(Cabal 字段) | darcs.cabal 中 Stability: Experimental |
| 官方仓库 | hub.darcs.net 上的 Darcs 仓库(用 Darcs 自举托管) | darcs.net 导航与下载页 |
| 发行版覆盖 | Repology 收录 88 个软件源 | Repology /api/v1/project/darcs |
| 安装渠道 | cabal install darcs、stack install darcs、Nix、各发行版包管理器 | darcs.net 首页下载区 |
版本节奏说明:Hackage 的 normal-version 列表显示 2.18 系列已发布 2.18.1~2.18.5 五个补丁版本,上一稳定系列是 2.16.5(再往前 2.14.5、2.12.5)。2.18.5 是当前最新正式版,Hackage 与官网口径一致。
二、软件概述
Darcs 是 David Roundy 于 2002 年发起的分布式版本控制系统,官方定位原文是 “a distributed, interactive, smart revision control system”。它最独特的地方不是命令长得像不像 Git,而是把「补丁(patch)」而不是「提交(commit)」当作版本库的第一公民。
在 Git/Mercurial 里,历史是一串提交组成的 DAG,每个提交是全仓库快照;在 Darcs 里,历史是一组带上下文的补丁,补丁的顺序可以被重排(commute),只要它们互不依赖。由此产生三个直接差异:
- 没有分支这一等公民:任意仓库都是分支,任意一组补丁也可以被看作分支。官网 Features 页给出的例子是给补丁统一命名
RT#123 ...,然后用darcs push -p 'RT#123'、darcs pull -p 'RT#123'、darcs send -p 'RT#123'、darcs log -p 'RT#123'把这一组补丁当作临时分支来推送、拉取、邮寄、审阅。 - 挑选粒度是补丁:
darcs record、pull、push都支持交互式逐 hunk 说 yes/no,因此可以只取别人的某一个补丁(cherry-pick 是原生能力,不依赖额外机制)。 - 邮件工作流是一等公民:
darcs send把补丁打成邮件发给维护者,维护者darcs apply审核入库,贡献者不需要提交权限(官网 Features 页明确描述)。
许可证为 GPL-2.0-or-later,对二次分发与商业内嵌的约束比 MIT/BSD 更强,但比 AGPL 宽松;企业内部自用不受影响。
三、Patch 理论:Darcs 的地基
理解下面四个概念,就能预判 Darcs 在大仓库上的表现。
3.1 补丁 = 带前后文的变换
一个 Darcs 补丁不是「文件新内容」,而是「在某个上下文(context)下,把一段旧内容变成新内容」的变换,同时记录了前向上下文和后向上下文。两条补丁只有在上下文兼容时才能先后应用。
3.2 交换(commutation)
若补丁 A、B 互不依赖(改的是不同文件,或同一文件的不同区域),则 AB 与 BA 等价,称 A 与 B 可交换。Darcs 在合并、拉取时会不断做交换,把两条历史线上的补丁交错排列成一条线性序列——这就是「无分支合并」的实现方式:合并不是生成一个 merge commit,而是把补丁重排后直接叠加。
3.3 合并与冲突
当 A、B 修改同一区域且无法交换时,Darcs 不会像 Git 那样留下 <<<<<<< 冲突块等待人工解决,而是把冲突记录成一种特殊的补丁(conflictor),并在工作区用标记语法标出冲突区域;用户解决后用 darcs resolve 或 darcs mark-conflicts 处理。好处是冲突本身进入历史、可被审计;代价是冲突补丁会长期影响后续交换的计算。
3.4 理论带来的性能边界
交换是两两进行的,最坏情况下冲突补丁之间的交换次数会随历史长度快速增长(补丁理论文献中讨论的「指数级合并」最坏情形)。工程上的表现是:
- 小/中型仓库、补丁粒度清晰、改动分散时,Darcs 的交互体验非常顺滑;
- 超大仓库、长期高频合并、大量二进制文件时,
pull/optimize的耗时与_darcs目录体积会明显劣化; - 因此 Darcs 官方与社区都建议定期执行
darcs optimize(压缩补丁包、重建索引),这也是本专栏命令篇单独用一节讲optimize的原因。
四、技术架构
Darcs 是纯 CLI、无守护进程的工具,不存在「服务端组件」这一层:
工作区/
└── _darcs/
├── patches/ # 补丁文件(gzip 压缩的补丁包)
├── prefs/ # 仓库级偏好:prefs、boring、binaries、motd、sources
├── pristine.hashed # 当前工作区对应的「原始树」缓存
├── index # 文件索引,加速 whatsnew/diff
└── inventory # 补丁清单(hashed inventory,darcs-2 格式)
- 本地即完整仓库:
darcs get拉下来的目录自带全部历史,离线可record,联网再push。 - 传输层:原生支持 SSH(
ssh://)、HTTP(S)(只读或配合 CGI/静态发布)、本地路径;darcs send走邮件(SMTP 或生成.patch文件)。 - 无中心服务:远程仓库就是一个普通目录(可以是裸的
_darcs目录),通过 SSH 执行远端darcs完成 push/pull。这也是本专栏按「纯 CLI 型」只写 4 篇(无服务端部署篇)的直接依据。
仓库格式方面,2.18 系列默认使用 darcs-2 格式(hashed inventory + 压缩补丁包),相比早期的 darcs-1 格式在补丁查找与完整性校验上有明显改进;跨格式的仓库不能直接互推,darcs get 时会按源仓库格式创建,混用前需确认。
五、功能特性
- 交互式记录:
darcs record逐 hunk 询问,可把一个工作区改动拆成多个语义清晰的补丁; - 补丁级 cherry-pick:
pull/push/send均可用-p/--patches按补丁名筛选; - 邮件协作:
send+apply构成无需提交权限的贡献链路; - 无分支管理:每个仓库即分支,fork 只需
darcs get; - 冲突可审计:冲突以补丁形式入库,
mark-conflicts/resolve显式处理; - 离线优先:本地记录、离线整理补丁(
amend/rebase/unrecord)后再推送; - 可选的强完整性:补丁包带哈希,
darcs repair可检测并修复仓库损坏; - 轻量托管:hub.darcs.net 提供免费托管,配合
darcsden可自建。
六、与 Git / Mercurial / Fossil 的量化对比
6.1 事实对照表(2026-10-27 实查)
| 维度 | Darcs | Git | Mercurial | Fossil |
|---|---|---|---|---|
| 首次发布 | 2002 | 2005 | 2005 | 2006 |
| 实现语言 | Haskell | C | Python + C | C |
| 许可证 | GPL-2.0-or-later | GPL-2.0 | GPL-2.0-or-later | BSD-2-Clause |
| 最新版本(Repology) | 2.18.5 | 2.56.0 | 7.2.4 | 2.28.0 |
| Repology 收录源数 | 88 | 744 | 531 | 146 |
| 历史模型 | 补丁集合(可交换) | 提交 DAG | 提交 DAG(revlog) | 提交 DAG + 内置工单/Wiki |
| 分支模型 | 无显式分支,仓库即分支 | 引用式分支 | 命名分支/书签 | 分支 |
| 合并产物 | 交换后的线性补丁序列 | merge commit | merge changeset | merge |
| 冲突表示 | 冲突补丁(conflictor) | 工作区冲突标记 | 工作区冲突标记 | 工作区冲突标记 |
| 默认远程协议 | SSH / HTTP / 邮件 | SSH / HTTPS / git | SSH / HTTP | HTTP(内置 CGI) |
| 官方托管 | hub.darcs.net | GitHub 等 | 多家 | 自托管为主 |
说明:版本号与收录源数均来自 Repology API 在 2026-10-27 的返回;Git 2.56.0、Mercurial 7.2.4、Fossil 2.28.0 为当日收录的最新正式版。
6.2 性能:定性与可解释的结论
Darcs 没有官方基准测试套件,社区公开对比也多为小规模手工测试,因此这里不给伪造的秒数,只给可解释的定性结论:
| 场景 | Darcs | Git | 说明 |
|---|---|---|---|
| 小型文本仓库(<1 万补丁)日常 record/pull | 快,交互体验好 | 快 | Darcs 的交互式拆分比 Git 的 add -p 更细 |
| 大型仓库首次 get | 偏慢 | 快 | 补丁需逐条应用并重建 pristine;Darcs 提供 --packs 优化下载 |
| 长期高频合并 | 明显变慢 | 稳定 | 冲突补丁导致交换次数增长,属理论固有成本 |
| 二进制大文件 | 不擅长 | 需 LFS | Darcs 无 LFS 类机制,补丁存储效率低 |
| 历史检索/日志 | 较慢 | 快 | 无 commit 索引,log 需遍历补丁 |
| 磁盘占用 | 偏大 | 较小 | _darcs/pristine + 补丁包双重存储,需 optimize 回收 |
6.3 学习曲线(作者评估,非基准)
| 工具 | 入门难度 | 精通难度 | 心智模型 |
|---|---|---|---|
| Darcs | 低(命令少、交互友好) | 高(补丁理论反直觉) | 补丁可交换,无分支 |
| Git | 中(概念多) | 高 | 快照 DAG + 引用 |
| Mercurial | 低-中 | 中 | 与 Git 类似但更一致 |
| Fossil | 低 | 中 | 单一可执行文件 + 内置协作 |
Darcs 的典型体验是「第一天就会用,第三个月才真正懂」:record/pull/push 极易上手,但一旦遇到冲突补丁、obliterate、rebase,没有 patch 理论背景就容易误操作。
6.4 生态
- 代码托管:GitHub/GitLab 均不原生支持 Darcs 协议;Darcs 项目自身托管在 hub.darcs.net,可自建 darcsden。
- CI/工具链:主流 CI 平台无 Darcs 集成,需要自建脚本;IDE 插件稀少。
- 发行版打包:Repology 88 个源,覆盖 Debian/Ubuntu/Fedora/Nix/Homebrew 等,但版本普遍滞后(Ubuntu 22.04 官方仓库仅 2.14.5-1build1,见安装篇实测)。
- 人才市场:会 Darcs 的工程师远少于 Git,团队交接成本高。
七、适用与不适用场景
适合:
- 中小型文本项目(源码、文档、配置、论文),补丁粒度清晰;
- 需要严格补丁评审的团队——
send/apply的邮件流让每个补丁都可独立审阅; - 网络不稳定或需要长时间离线的环境——本地即完整仓库;
- 教学与研究——Darcs 是补丁理论最完整的工程实现;
- Haskell 生态项目——工具链同源,社区习惯一致。
不适合:
- 巨型单体仓库(数十万文件、百万级提交);
- 二进制资源密集(游戏美术、数据集、视频),无 LFS;
- 深度绑定 GitHub/GitLab 的团队(PR、Actions、Code Owners 等);
- 高频并行合并的大团队;
- 需要子模块、稀疏检出、部分克隆等现代工作流能力的项目。
八、部署形态结论
Darcs 没有服务端守护进程、没有官方预编译安装包、没有官方一键部署清单,远程协作只需要目标机装好 darcs 并开放 SSH(或静态 HTTP 发布)。因此本专栏按纯 CLI 型交付 4 篇:介绍选型(本篇)、Ubuntu 22.04 安装、配置参数、CLI 命令;不写服务端/Compose 部署篇,避免为不存在的形态编造内容。若团队需要 Web 浏览界面,那是 hub.darcs.net 或第三方 darcsden 的范畴,不属于 Darcs 本体。
九、排障实录(选型阶段的三个真问题)
问题 1:以为要像 GitLab 那样先部署一个「Darcs 服务端」。
真相:不需要。远程仓库就是一个含 _darcs 的目录,darcs push ssh://user@host/path 即可,服务端只要求有 darcs 可执行文件与 SSH 权限。把 Darcs 当「需要部署的服务」会导致架构方案整体跑偏。
问题 2:直接用 cabal install darcs 在 1C1G 小机上编译,OOM 失败。
真相:Darcs 是大型 Haskell 项目,GHC 编译期内存需求高,官方推荐用 stack 或发行版预编译包。小内存机器应优先 apt 安装(版本旧但可用),或加到 ≥4 GB 内存/交换区再编译。安装篇会给出两条路线的实测对比。
问题 3:把 Git 仓库直接 darcs get 过来,发现历史对不上。
真相:Darcs 与 Git 的仓库格式、历史模型都不同,不能互读;迁移需用 darcs convert 系列工具或第三方桥接,且补丁边界会重排。选型阶段就要接受「迁入迁出都有成本」。
十、参考资料
- darcs.net 首页(最新版本 2.18.5、安装渠道),查询日期 2026-10-27
- darcs.net / Features(离线、邮件协作、无分支模型、补丁筛选示例),查询日期 2026-10-27
- Hackage
darcs-2.18.5/darcs.cabal(许可证、语言、Stability 字段),查询日期 2026-10-27 - Hackage
preferred.json(2.18.5 为 normal-version 首位),查询日期 2026-10-27 - Repology API
/api/v1/project/{darcs,git,mercurial,fossil}(版本与收录源数),查询日期 2026-10-27
下一篇:按本专栏顺序阅读 《Ubuntu 22.04 安装 Darcs 2.18.5 指南》、《Darcs 2.18.5 配置参数详解》、《Darcs 2.18.5 常用 CLI 命令详解》。