在这种琐碎的合并中出了什么问题?

时间:2019-06-30 20:47:47

标签: mercurial

编辑:这当然不是在stackoverflow上的好习惯,我对此表示诚挚的歉意,但是似乎我不清楚我正在执行的确切步骤,这会引起混乱。因此,我决定重写这篇文章,并更清楚地说明我正在运行哪些确切的命令以及以什么顺序重现我的经验。

因为之前我不得不处理Mercurial中的虚假合并,所以做了一些实验:

cd example
hg init

创建example.dart

num add(num a, num b) {
  return a - b;
}
hg add .\example.dart
hg commit -m "bogus add()"
hg branch other

添加到example.dart

num sub(num a, num b) {
  return a - b;
}
hg commit -m "correct sub()"
hg update default
hg commit -m "fix add()"

(note by me: Mercurial messes up some characters)
hg log -G
@  ─nderung:        2:19a3c127981b
|  Marke:           tip
|  Vorgõnger:       0:ac1d30ac2dda
|  Nutzer:          Marvin
|  Datum:           Mon Jul 01 19:31:24 2019 +0200
|  Zusammenfassung: fix add()
|
| o  ─nderung:        1:645416c58a38
|/   Zweig:           other
|    Nutzer:          Marvin
|    Datum:           Mon Jul 01 19:23:40 2019 +0200
|    Zusammenfassung: correct sub()
|
o  ─nderung:        0:ac1d30ac2dda
   Nutzer:          Marvin
   Datum:           Mon Jul 01 19:19:47 2019 +0200
   Zusammenfassung: bogus add()

hg update other
hg graft 19a3c127981b

hg log -G
@  ─nderung:        3:567c99a23b17
|  Zweig:           other
|  Marke:           tip
|  Vorgõnger:       1:645416c58a38
|  Nutzer:          Marvin
|  Datum:           Mon Jul 01 19:31:24 2019 +0200
|  Zusammenfassung: fix add()
|
| o  ─nderung:        2:19a3c127981b
| |  Vorgõnger:       0:ac1d30ac2dda
| |  Nutzer:          Marvin
| |  Datum:           Mon Jul 01 19:31:24 2019 +0200
| |  Zusammenfassung: fix add()
| |
o |  ─nderung:        1:645416c58a38
|/   Zweig:           other
|    Nutzer:          Marvin
|    Datum:           Mon Jul 01 19:23:40 2019 +0200
|    Zusammenfassung: correct sub()
|
o  ─nderung:        0:ac1d30ac2dda
   Nutzer:          Marvin
   Datum:           Mon Jul 01 19:19:47 2019 +0200
   Zusammenfassung: bogus add()

这会在example.dart中产生预期的结果:

num add(num a, num b) {
  return a + b;
}

num sub(num a, num b) {
  return a - b;
}
hg update default
hg merge other
hg commit -m "merge with other"

hg log -G
@    ─nderung:        4:a76695f39931
|\   Marke:           tip
| |  Vorgõnger:       2:19a3c127981b
| |  Vorgõnger:       3:567c99a23b17
| |  Nutzer:          Marvin
| |  Datum:           Mon Jul 01 19:37:18 2019 +0200
| |  Zusammenfassung: merge with other
| |
| o  ─nderung:        3:567c99a23b17
| |  Zweig:           other
| |  Vorgõnger:       1:645416c58a38
| |  Nutzer:          Marvin
| |  Datum:           Mon Jul 01 19:31:24 2019 +0200
| |  Zusammenfassung: fix add()
| |
o |  ─nderung:        2:19a3c127981b
| |  Vorgõnger:       0:ac1d30ac2dda
| |  Nutzer:          Marvin
| |  Datum:           Mon Jul 01 19:31:24 2019 +0200
| |  Zusammenfassung: fix add()
| |
| o  ─nderung:        1:645416c58a38
|/   Zweig:           other
|    Nutzer:          Marvin
|    Datum:           Mon Jul 01 19:23:40 2019 +0200
|    Zusammenfassung: correct sub()
|
o  ─nderung:        0:ac1d30ac2dda
   Nutzer:          Marvin
   Datum:           Mon Jul 01 19:19:47 2019 +0200
   Zusammenfassung: bogus add()

历史现在看起来像预期的那样。但是,合并结果不会:

num add(num a, num b) {
  return a + b;
}

num sub(num a, num b) {
}

有趣的是,合并算法清楚地切出sub()的主体,而不会产生任何冲突。

该实验是在装有新安装的Mercurial 4.9.1的Windows 10计算机上进行的。唯一安装的差异工具是KDiff3,它带有Mercurial和TortoiseHg(我没有使用)。标准设置未更改,没有插件被激活。

也许这只是一些奇怪的极端情况,尽管我会对引起它的原因非常感兴趣。如果您能提供任何见解,我将非常高兴。像这样的虚假合并会引起极大的头痛,因此我认为这是相关的。

2 个答案:

答案 0 :(得分:3)

我无法复制您的经历。这是我的尝试:

$ mkdir hg
$ cd hg
$ hg init
$ cat > exp.lang << 'end'
> num add(num a, num b) {
>   return a - b;
> }
> end
$ hg add exp.lang
$ hg commit -m initial
$ hg branch other
marked working directory as branch other
(branches are permanent and global, did you want a bookmark?)
$ cat >> exp.lang << 'end'
> 
> num sub(num a, num b) {
>   return a - b;
> }
> end
$ hg commit -m 'add sub()'
$ hg checkout default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ ed exp.lang
42
2
  return a - b;
s/-/+/
w
42
q
$ hg commit -m 'fix bug'

据我所知,这就是您所说的:修复默认分支上的错误。让我们嫁接此修复程序,看看它是否正确:

$ hg checkout other
$ hg graft -r 2
grafting 2:2670b3299c96 "fix bug" (tip)
merging exp.lang
$ hg lga                 # lga is a graphical log alias
@  3:811f4d1a7dc4:draft  other tip Chris Torek
|  fix bug (54 seconds ago)
|
| o  2:2670b3299c96:draft  Chris Torek
| |  fix bug (54 seconds ago)
| |
o |  1:a780b1c8c579:draft  other Chris Torek
|/   add sub() (112 seconds ago)
|
o  0:b085834fc520:draft  Chris Torek
   initial (3 minutes ago)

$ cat exp.lang
num add(num a, num b) {
  return a + b;
}

num sub(num a, num b) {
  return a - b;
}

到目前为止,非常好-就我所知,我已复制了您的设置。现在:

$ hg checkout default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge other
warning: conflicts while merging exp.lang! (edit, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon

合并失败,因为Mercurial需要人工帮助。这是Mercurial看到的:

$ cat exp.lang
num add(num a, num b) {
<<<<<<< working copy
  return a + b;
||||||| base
  return a - b;
=======
  return a + b;
}

num sub(num a, num b) {
  return a - b;
>>>>>>> merge rev
}

版本0之前的文件的基本副本具有错误:add返回a - b。当前(默认)分支版本2的提示如下:

$ hg abort
aborting the merge, updating back to 2670b3299c96
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cat exp.lang
num add(num a, num b) {
  return a + b;
}

这是我们应该期望的:该错误已修复。我们要合并的修订版具有相同的单行修补程序, 也会在最后一个大括号之前插入所有其他内容(四行)。 VCS应该使用哪一种,一线修复还是五线修复?它不知道,因此停止寻求帮助。

答案 1 :(得分:0)

Mercurial(TortoiseHG)4.9.1,与@torek撰写的结果相同

THG的合并失败版本

% hg merge --config=ui.merge=:merge --verbose 3
resolving manifests
merging functions.c
warning: conflicts while merging functions.c! (edit, then use 'hg resolve --mark')
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon

和(预期)文件在处理过程中的状态(在上述合并之后立即)

num add(num a, num b) {
  return a + b;
<<<<<<< working copy
=======
}

num sub(num a, num b) {
  return a - b;
>>>>>>> merge rev
}

添加

对于常用合并工具,此合并不能是无冲突的合并(此处的GUI演示会更好)

Merging

因为合并结果 IS 冲突区域中的灰色字符串/(1)om屏幕截图/,该(冲突)必须以任何方式解决。但是,如果我们在观察了“其他”文件(merge-panel的右侧,屏幕截图的(2)区域)和您描述的结果之后假设

num sub(num a, num b) {
}

您的默认合并工具可以是指示自己的政策而不是解决的工具,可以回答问题“为什么发生”。

稍微深入一点:如果您的默认合并工具某种程度上是“ internal:other”,那么

  • “另一面”的绿色部分(2)必须出现在合并结果中(根据选择mergetool的要求)
  • 仅忽略了冲突区域(1)
  • 左括号}(3)在合并的两面都是通用块,并转移到合并结果