4

我的困惑源于从此处获取的以下声明:

当拉取相互冲突的补丁(例如,更改文件的相同部分)时,Darcs 会检测到冲突并将其标记在存储库内容中。然后它让用户解决问题。

这似乎与我所看到的不一致,因此我使用 darcs 2.5.2 创建了以下工作流程:

  1. 创建回购 foo;
  2. 在 foo 中创建一个非空文件并记录下来;
  3. 将 foo 克隆到 bar;
  4. 删除foo中的文件并记录;
  5. 在bar中的文件中添加另一行并记录它;
  6. 从 foo 拉入 bar,获取冲突通知;

采取这些步骤后,我darcs whatsnew在 bar 中运行,并显示了两个“补丁原语”:

  1. 删除所有“foo 中的非空文件”的大块头,但没有提及在 bar 中添加和记录的行;
  2. 删除文件的 rmfile。

我的问题是:为什么没有提及添加并记录在栏中的行?

如果我darcs revert在 bar 中运行,那么一切都是有道理的:我看到“非空文件”受到两个冲突补丁的影响,根据从这里获取的语句:

命令 darcs revert 将删除冲突标记并恢复到冲突补丁之前的状态。

但是,如果我运行darcs mark-conflicts,我会回到与拉动后相同的状态,使用上面提到的两个“补丁原语”,并且没有提及添加并记录在 bar.xml 中的行。


供参考/复制这里是我从命令行的完整工作流程:

$ mkdir foo
$ cd foo/
foo$ darcs initialize

foo$ touch shopping
foo$ vi shopping          <-- add a couple of lines
foo$ darcs add shopping

foo$ darcs record 
addfile ./shopping
Shall I record this change? (1/2)  [ynW...], or ? for more options: y
hunk ./shopping 1
+cake
+pie
Shall I record this change? (2/2)  [ynW...], or ? for more options: y
What is the patch name? Added shopping
Do you want to add a long comment? [yn]n
Finished recording patch 'Added shopping'

foo$ cd ..
$ darcs get foo/ bar
$ cd bar/

bar$ vi shopping    <-- add another line
bar$ darcs record 
hunk ./shopping 2
+beer
Shall I record this change? (1/1)  [ynW...], or ? for more options: y
What is the patch name? Added beer
Do you want to add a long comment? [yn]n
Finished recording patch 'Added beer'

bar$ cd ../foo
foo$ rm shopping 
foo$ darcs record 
hunk ./shopping 1
-cake
-pie
Shall I record this change? (1/2)  [ynW...], or ? for more options: y
rmfile ./shopping
Shall I record this change? (2/2)  [ynW...], or ? for more options: y
What is the patch name? Removed shopping
Do you want to add a long comment? [yn]n
Finished recording patch 'Removed shopping'

foo$ cd ../bar
bar$ darcs pull
Pulling from "../foo"...
Mon Nov 14 19:26:44 GMT 2011  dukedave@gmail.com
  * Removed shopping
Shall I pull this patch? (1/1)  [ynW...], or ? for more options: y
Backing up ./shopping(-darcs-backup0)
We have conflicts in the following files:
./shopping
Finished pulling and applying.

bar$ darcs whatsnew 
hunk ./shopping 1
-cake
-pie
rmfile ./shopping
4

1 回答 1

7

如果您运行darcs changes -vinside bar,您将看到更改的历史记录,包括由于您提取冲突补丁而引入的冲突器。

我已将您的示例总结为稍微短一些的内容:

DARCS=/usr/bin/darcs

$DARCS init --repo foo
cd foo

echo 'a' > myfile
$DARCS add myfile && $DARCS record -am 'Add myfile'

$DARCS get . ../bar

rm myfile
$DARCS record -am 'Remove myfile'

cd ../bar

echo 'b' >> myfile
$DARCS record -am 'Change myfile'

$DARCS pull -a ../foo

$DARCS changes -v

现在,在那之后,我看到了这个输出darcs changes -v

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Remove myfile
    conflictor [
    hunk ./myfile 2
    +b
    ]
    |:
    hunk ./myfile 1
    -a
    conflictor {{
    |:
    hunk ./myfile 2
    +b
    |:
    hunk ./myfile 1
    -a
    }} []
    |hunk ./myfile 1
    |-a
    |:
    rmfile ./myfile

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Change myfile
    hunk ./myfile 2
    +b

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Add myfile
    addfile ./myfile
    hunk ./myfile 1
    +a

那么,让我们解释一下“Remove myfile”的疯狂输出。“Remove myfile”在 foo 中存在如下:

Tue Nov 15 19:44:38 GMT 2011  Owen Stephens <darcs@owenstephens.co.uk>
  * Remove myfile
    hunk ./myfile 1
    -a
    rmfile ./myfile

因此,在第 1 行有一个大块并删除了文件。

将“remove myfile”拉入 bar,我们通过引入特殊的“conflictor”原语来修改补丁内容,这些原语表示“Remove myfile”中与 bar 中其他原语冲突的原语。注意这里没有信息丢失 - 我们总是可以通过取消冲突更改来恢复原始原语 - 在这种情况下,取消“更改 myfile”。

冲突者令人困惑,但 AFAICT 本质上将与当前补丁 x 冲突的更改分为 2 组:“ix”是一组补丁,包括:i)与 x 冲突的补丁和 repo 中的其他补丁 ii)补丁与与 x "xx" 冲突的补丁冲突,这是仅与补丁 x 冲突的补丁序列。我认为这样做的原因是冲突者具有“撤消”导致冲突的原语的效果,但只有那些尚未被另一个冲突者撤消的原语。

我们看到的输出类似于:

"conflictor" ix "[" xx "]" x

我在滥用符号,但希望您能对此有所了解(请参阅 darcs.net 存储库中的 src/Darcs/Patch/V2/(Real.hs|Non.hs) 以获取完整故事)

在这种情况下,“删除 myfile”有 2 个原始补丁,并且(在这种情况下)拉入 bar 时有 2 个相应的冲突。

第一个原语(从 myfile 中删除第 1 行)仅与“更改 myfile”中的原语冲突(将 'b' 添加到 myfile 的第 2 行),因此这是第一个冲突者:

conflictor [    <--- The start of xx (no ix here)
hunk ./myfile 2
+b
]               <--- The end of xx
|:
hunk ./myfile 1 <--- x
-a

注意(“|:”是一个标记,将“非”原语的上下文与原语本身分隔 - 我不会尝试进一步解释它,只需阅读下面的 |: 以查看有问题的原语)

第二个原语 (remove myfile) 稍微复杂一点: (rmfile myfile) 与 (add 'b' to line 2 of myfile) 冲突,我们知道这与 (remove line 1 from myfile) 冲突,所以它们都进入“ ix”,在“xx”中没有补丁。我将删除不必要的“|:”分隔符并将内容隔开:

conflictor {{

hunk ./myfile 2
+b

hunk ./myfile 1
-a

}} 
[]               <--- no xx

|hunk ./myfile 1 <--- start of x
|-a
|:
rmfile ./myfile  <--- end of x

最后的(rmfile myfile)有一些上下文来识别我们所指的确切原语(我不太确定为什么/如何需要,但我们确实存在),它由前导'|'s 和由“|:”分隔。

最后,尝试解释darcs whatsnewin foo;的输出。当多个补丁发生冲突时,我认为冲突者的实际效果是“撤消”任何冲突的补丁,两者都不产生效果;给出了一些解释的开始:http ://en.wikibooks.org/wiki/Understanding_Darcs/Patch_theory_and_conflicts 。

我认为您所看到的是“Change myfile”和“Remove myfile”分别调用它们的强制换向的A结果B。然后将两者合并,Darcs 创建A^-1和通勤A^-1B给予B'(A^-1)'在哪里B'具有A^-1(因为我们强制通勤工作)的效果,这意味着B'(即合并的“删除我的文件”)的效果实际上只是撤消添加由“更改我的文件”所做的行。

我还没来得及看看是如何darcs mark-conflicts工作的,所以我还不能解释你darcs changes在 bar 中看到的工作变化。

于 2011-11-15T20:18:28.070 回答