Darcs 2.18.5 常用 CLI 命令详解

Darcs 2.18.5 常用 CLI 命令详解:按建库/提交/同步/查询/冲突/维护六段工作流实测 init、clone、get、put、pull、push、send、apply、record、amend、rollback、revert、obliterate、unrecord、log、whatsnew、diff、add、remove、move、replace、mark-conflicts、tag、optimize、repair 等命令,逐条真实回显,含冲突标记格式与 optimize 子命令实战。

DarcsDarcs版本控制Haskell2026/10/27

Darcs 2.18.5 常用 CLI 命令详解

目标:按「建库获取 → 日常提交 → 同步协作 → 查询 → 冲突 → 维护」六段工作流,把 Darcs 2.18.5 的常用命令逐条跑通。每条命令都给真实输入与逐行回显,测试环境 Ubuntu 22.04.5 + Darcs 2.18.5,作者 admin <admin@example.com>,仓库 /root/lab/d1、/root/lab/d2。

一、命令命名变化(先看这一节)

Darcs 2.18 做了一轮命令改名,旧名保留为别名,但帮助里会标注。实测:

旧名新名实测回显
darcs initdarcs initializedarcs init --help 显示 Usage: darcs initialize ...
darcs getdarcs clonedarcs get --help 显示 Alias for 'darcs clone'.
darcs changesdarcs logdarcs changes --help 显示 Alias for 'darcs log'.
darcs put已废弃darcs put --help 显示 Deprecated command, replaced by clone.
darcs resolve不存在darcs resolve → No such command 'resolve'

所以本文标题里的 resolve 要按实际替换为 mark-conflicts + 手工编辑 + record,详见第六节。

二、建库与获取

2.1 darcs init / initialize

darcs init d1
Finished initializing repository.

默认创建 darcs-2 格式 + 工作区;--darcs-3 可建新格式(实验性),--darcs-1 为兼容旧版,--no-working-dir 建裸仓库。查看格式:

darcs show repo
         Format: hashed, darcs-2
           Root: /root/lab/d1
   PristineType: HashedPristine
          Cache: thisrepo:/root/lab/d1, cache:/root/.cache/darcs
     PatchIndex: enabled, but not yet created
    Num Patches: 4
      Weak Hash: 7e5b1dbd728c5cbd675da50970c2f25d463c5919

2.2 darcs clone(等价旧 get)

darcs clone d1 d2
Copying patches, to get lazy repository hit ctrl-C...
Finished cloning.

darcs get repoA repoG 回显相同(末尾 Finished cloning.),两者等价。--lazy 只取元数据、按需拉补丁,适合大仓库;本地路径克隆最快,SSH 克隆见配置篇。

2.3 darcs put(已废弃)

darcs put /root/lab/repoC
This command is deprecated.

To clone the current repository to a ssh destination, use the syntax `darcs clone
. user@server:path` .

新写法:darcs clone . user@server:/path。

三、日常提交

3.1 darcs add

darcs add app.py README.md
Adding './README.md'
Adding './app.py'
Finished adding:
./README.md
./app.py

注意顺序按字典序输出,与传入顺序无关。新增文件不会自动入库,必须显式 add。

3.2 darcs whatsnew

darcs whatsnew
addfile ./hello.txt
hunk ./hello.txt 1
+hello darcs
+second line
addfile ./notes.txt
hunk ./notes.txt 1
+alpha
+beta

-s/--summary 只输出单行摘要:M ./hello.txt +1;-l 连未跟踪文件一起列出(实测显示 a ./hello2.txt);--look-for-adds 等价。

3.3 darcs diff

未记录变更的 unified diff:

darcs diff
diff -rN -u old-repoA/hello.txt new-repoA/hello.txt
--- old-repoA/hello.txt	1970-01-01 00:00:00.000000000 +0000
+++ new-repoA/hello.txt	2026-10-27 12:30:38.308239017 +0000
@@ -0,0 +1,2 @@
+hello darcs
+second line

darcs diff --last 1 对最近一个补丁做差异;配合 --unified=N 控制上下文行数。

3.4 darcs record

darcs record -a -m 'init app'
Finished recording patch 'init app'

交互模式不加 -a -m,会逐文件、逐 hunk 询问;补丁边界因此可以切得很细。--author 可临时覆盖作者。

3.5 darcs amend(修改最后一个补丁)

echo y | darcs amend -m 'amend demo (edited)'
patch 2dcd1c4616810a179a67e6be6495ce559a7c51ec
Author: admin <admin@example.com>
Date:   Tue Oct 27 12:31:15 UTC 2026
  * amend demo
Shall I amend this patch? [yNjk...], or ? for more options: Finished amending patch.

amend 默认会先展示补丁再要求确认,脚本里必须喂 y。完成后:

patch 7579bf643ef7987fdc347be7fa75c4c2a2e0d4c2
  * amend demo (edited)

--unrecord 反向操作(把改动从补丁里拿出来),--record 追加更多改动(默认)。

3.6 darcs revert / unrevert

darcs revert -a
darcs unrevert -a
Finished reverting.
Finished unreverting.

revert 丢弃未记录改动,但会保存一份可 unrevert 的备份——误删的救命命令。clean 是 revert -l 的别名。

3.7 darcs unrecord

darcs unrecord --last 1 -a
Finished unrecording.

补丁从历史移除,改动留在工作区(与 obliterate 的区别),随后可重新 record 切成更合理的补丁。

3.8 darcs rollback

darcs rollback -a -p 'A: add line'
Changes rolled back in working tree

把指定补丁的逆操作应用到工作区,形成未记录改动,不改变历史。常用于「先撤销看看,再决定是否记录」。

3.9 darcs obliterate

printf 'y\ny\n' | darcs obliterate -p 'rename and cleanup'
patch aef8855be8529bf52c8cc087168237822fa9e21a
Author: admin <admin@example.com>
Date:   Tue Oct 27 12:31:33 UTC 2026
  * rename and cleanup
Shall I obliterate this patch? (1/1)  [ynW...], or ? for more options: Do you want to Obliterate these patches? [Yglqk...], or ? for more options: Backing up notes.txt(.~0~)
Finished obliterating.

obliterate 彻底删除补丁(历史 + 工作区一起回退),需要两次确认,并生成 .~0~ 备份文件。实测 -a -p 组合会返回 No patches selected!,只用 -p(或 --last N)再喂确认。

3.10 darcs remove / move / replace

darcs move hello.txt hello2.txt
darcs replace darcs Darcs notes.txt
darcs remove notes.txt
Finished moving: ./hello.txt to: ./hello2.txt
Will stop tracking:
./notes.txt

replace 成功时无输出,用 whatsnew 验证:

replace ./README.md [A-Za-z_0-9] readme README

replace 是 Darcs 特有的「词替换补丁」,比整文件 diff 更易合并;move 是重命名补丁,保留历史。

四、同步与协作

4.1 darcs push

darcs push -a ../d1
reading patch bundle from stdin...
Finished applying.
Pushing to "/root/lab/d1"...
Finished pushing.

本地路径推送会先走 apply 通道,因此出现 reading patch bundle from stdin...,属正常。SSH 推送直接显示 Pushing to "ssh://..."。

4.2 darcs pull

darcs pull -a ../repoA

冲突时:

We have conflicts!
Affected paths:
./hello.txt
Pulling from "/root/lab/repoA"...
Backing up /root/lab/repoB/hello.txt(.~0~)
Finished pulling.

无新补丁时:

No remote patches to pull in!

--set-default 可顺手把该远端写进 _darcs/prefs/defaultrepo,之后 darcs pull -a 不再需要路径。

4.3 darcs send 与 darcs apply(邮件流)

darcs send -a -o ../bundle.patch ../repoD
By the way, to change the default remote repository to
      /root/lab/repoD,
you can issue the same command with the --set-default flag.
Minimizing context, to send with full context hit ctrl-C...
File content did not change. Continue anyway? [yn]Wrote patch to /root/lab/bundle.patch.

send 在上下文最小化时会问一句,脚本里用 echo y | 或直接回车。生成的 bundle 头部:

2 patches for repository /root/lab/repoD:

patch 7579bf643ef7987fdc347be7fa75c4c2a2e0d4c2
  * amend demo (edited)

接收方:

darcs apply -a ../bundle.patch
We have conflicts!
Affected paths:
./hello.txt
Refusing to apply patches leading to conflicts.
If you would rather apply the patch and mark the conflicts,
use the --mark-conflicts or --allow-conflicts options to apply

加 --mark-conflicts 后成功:

Backing up /root/lab/repoD/hello.txt(.~0~)
Finished applying.

send 不配置 --output 时会调用 sendmail 直接发信,适合「无提交权限」的开源协作。

4.4 darcs fetch

darcs fetch -a ../repoA
Pulling from "/root/lab/repoA"...
No remote patches to pull in!

只下载补丁不入库,后续可选择性 apply/pull,用于预审。

4.5 darcs tag / show-tags

darcs tag v1.0
darcs show tags
Finished tagging 'TAG v1.0'.
v1.0

Tag 本身也是一条补丁,记录在历史里(darcs log 显示 tagged v1.0),没有 Git 的轻量/附注之分。

五、查询

5.1 darcs log / changes

darcs log --last 3
patch 93273d057459d115336e58e619e4e96bdfc26062
Author: admin <admin@example.com>
Date:   Tue Oct 27 12:39:11 UTC 2026
  tagged v1.0

patch c8bd62d7939e48b6380dbfa6d41fe03cf997d8d1
Author: admin <admin@example.com>
Date:   Tue Oct 27 12:39:11 UTC 2026
  * doc from d1

patch ca539e594e856f7935db3f06e3b295f872be41f4
Author: admin <admin@example.com>
Date:   Tue Oct 27 12:39:11 UTC 2026
  * feature from d2

changes 是别名,输出完全一致。常用过滤:-p REGEXP 按补丁名、--last N、--from-tag、--match。

5.2 darcs annotate

逐行标注最后修改它的补丁:

darcs annotate hello2.txt
Creating a patch index, please wait. To stop press Ctrl-C
Created patch index.
1: patch 92e491863c21b771491041c8eed35bc2829f0623
  * initial import
2: patch d69705b85b6d2c5f18b0e2e2c4ea284c7658c877
  * A: add line

1:    admin@example.com   #1 | hello darcs 
2:                           | second line 
3:    admin@example.com   #2 | line from A 

首次会建 patch index(可 darcs optimize enable-patch-index 预热)。

5.3 darcs show

darcs show repo
darcs show files
./README.md
./app.py

show files 只列已跟踪文件;-l 含未跟踪,--directories 只看目录。

六、冲突处理(2.18 的正确姿势)

6.1 冲突标记长什么样

pull 冲突后工作区文件:

hello darcs
second line
v v v v v v v
=============
line from A
*************
line from B
^ ^ ^ ^ ^ ^ ^

含义:v v v 起、======= 分隔、******* 再分隔、^ ^ ^ 止。Darcs 会把冲突记录成冲突补丁,并生成 hello.txt.~0~ 备份。

6.2 mark-conflicts

darcs mark-conflicts
No conflicts to mark.

作用是「把工作区里未标记的冲突重新打上标记」,不是解决冲突。当前无冲突时输出上面这句。

6.3 解决冲突的实际流程

Darcs 没有 resolve 子命令,正确流程是:

  1. 手工编辑文件,删掉四类标记,保留想要的内容;
  2. darcs whatsnew 确认改动;
  3. darcs record -a -m 'resolve conflict: keep both' 把解决结果记成新补丁。

实测:

darcs whatsnew
darcs record -a -m 'resolve conflict: keep both'
hunk ./hello.txt 3
+line from A
+line from B
Finished recording patch 'resolve conflict: keep both'

若想放弃解决,darcs revert -a 回到冲突标记状态。

6.4 apply 时的冲突

如 4.3 所示,apply 默认拒绝产生冲突的补丁;加 --mark-conflicts 应用并标记,加 --allow-conflicts 应用但不标记(危险,慎用)。

七、维护

7.1 darcs optimize(必须带子命令)

darcs optimize
Command 'optimize' requires a subcommand!

Usage: darcs optimize SUBCOMMAND [OPTION]...
Subcommands:
  clean                Garbage collect pristine, inventories and patches
  http                 Optimize repository for getting over network
  reorder              Reorder the patches in the repository
  enable-patch-index   Enable patch index
  disable-patch-index  Disable patch index
  compress             Compress hashed files
  uncompress           Uncompress hashed files (for debugging)
  relink               Replace copies of hashed files with hard links
  upgrade              Upgrade repository to latest compatible format
  cache                Garbage collect global cache

实测三个最常用:

darcs optimize clean
darcs optimize cache
darcs optimize enable-patch-index
Done cleaning repository!
Migrating global cache to bucketed format.
Done making bucketed cache!
Done cleaning global cache!
Done enabling patch index!

注意 --patch-index 这种旧式选项在 2.18.5 已不可用(unrecognized option),要用 enable-patch-index 子命令。大仓库长期使用后体积膨胀,clean + compress 是例行维护项。

7.2 darcs repair

darcs repair
The repository is already consistent, no changes made.

仓库损坏(异常断电、NFS 写入失败)时先 darcs repair,再做 optimize。

八、一条完整工作流(d1 ↔ d2)

darcs init d1 && cd d1
darcs add app.py README.md
darcs record -a -m 'init app'
cd .. && darcs clone d1 d2 && cd d2
# 修改 app.py
darcs record -a -m 'feature from d2'
darcs push -a ../d1
cd ../d1
# 修改 README.md
darcs record -a -m 'doc from d1'
darcs pull -a ../d2
darcs tag v1.0

对应回显:

Finished initializing repository.
Finished recording patch 'init app'
Copying patches, to get lazy repository hit ctrl-C...
Finished cloning.
Finished recording patch 'feature from d2'
Pushing to "/root/lab/d1"...
Finished pushing.
Finished recording patch 'doc from d1'
No remote patches to pull in!
Finished tagging 'TAG v1.0'.

最后 darcs log --last 3 能看到 tagged v1.0、doc from d1、feature from d2 三条。

九、排障实录

1)darcs resolve 报 No such command 'resolve'

2.18 已移除该命令。解决冲突 = 手工编辑 + record;重建标记 = mark-conflicts。

2)darcs obliterate -a -p 'xxx' 报 No patches selected!

-a 与 -p 组合在本版本行为异常。改用 printf 'y\ny\n' | darcs obliterate -p 'xxx' 或 --last 1,并准备两次确认。

3)darcs send 卡在 File content did not change. Continue anyway? [yn]

上下文最小化阶段的确认。echo y | darcs send -a -o bundle.patch <target> 即可;交互终端直接回车。

4)darcs push 本地路径出现 reading patch bundle from stdin...

本地/HTTP 通道走 apply 模式,正常现象;SSH 通道不会出现。

5)darcs apply 拒绝应用

默认安全策略:会产生冲突就拒绝。确认影响后加 --mark-conflicts;不要图省事用 --allow-conflicts。

6)darcs amend 在脚本里直接退出

它先展示补丁再问 Shall I amend this patch?,必须 echo y |;-a 不会替你回答这个确认。

十、速查表

任务命令
建库darcs init DIR
克隆darcs clone SRC DST
看待提交darcs whatsnew / darcs diff
提交darcs add + darcs record -a -m MSG
改上一条echo y | darcs amend -m MSG
撤销未提交darcs revert -a / darcs unrevert -a
撤销已提交但保留改动darcs unrecord --last 1 -a
彻底删除补丁darcs obliterate -p NAME
同步darcs pull -a / darcs push -a
邮件协作darcs send -o bundle / darcs apply bundle
查历史darcs log --last N
打标签darcs tag v1.0 / darcs show tags
冲突手工编辑 + darcs record;mark-conflicts 重建标记
维护darcs optimize clean / optimize cache / repair

配置项与默认选项见 《Darcs 2.18.5 配置参数详解》,安装见 《Ubuntu 22.04 安装 Darcs 2.18.5 指南》,选型见 《Darcs 2.18.5 介绍与选型指南》。