【问题标题】:TFS merge algorithm issueTFS 合并算法问题
【发布时间】:2012-06-10 11:41:46
【问题描述】:

我们使用 TFS 2010 并拥有三个分支:Dev -> QA -> Production。

在这个特定示例中,我们决定将方法参数类型和名称从“Guid reportGuid”更改为“int reportId”。我们在 QA 分支中进行了此更改并将其签入。现在我正尝试将此更改从 QA 拉到 Dev 分支。通常它是在相反的方向完成的,但在这种特殊情况下,我们做了我们所做的。 Here 是合并工具的截图。正如您从屏幕截图中看到的那样,在 Dev 分支中对文件的最后一次签入获得了变更集编号 30282 和 QA - 31002(比 30282 更新)。至于我,很明显新的变化应该覆盖旧的变化。但是 TFS 合并的作用恰恰相反。它将 Dev 分支 (30282) 中的旧代码应用于 QA 分支 (31002) 中的新代码,结果没有得到更改。

有人能解释一下为什么 TFS 合并会这样吗? 提前致谢。

【问题讨论】:

  • 您上传图片的链接无效。
  • 谢谢,雅各布。我更新了图片链接。
  • 需要注意的是,图中的工具不是三向合并工具。可能有点不直观,一个三向合并工具will show four windows of text, as with kdiff3 -- 1.) “你的” 2.) 他们的 3.) 1. & 2. 和 4.) 你的共享父级'现在正在编辑。
  • @ruffin 不。它绝对是一个三向合并工具。无论该工具对祖先使用单独的窗口,对合并输出使用另一个窗口,还是将它们组合起来,算法都是相同的。两个文件的毫无根据的合并无法识别更改。
  • @EdwardThomson:我们显然同意你最后一点的真理。如果您说 CS31002 反映了共同的祖先,而 30282 是蓝色的以反映变化,那很好。但是,如果 31002 和 30282 both 与祖先不同,它会显示什么?我的意思仅限于说您无法通过查看工具的图片来推断关系。如果您希望将我的评论修改为“奇怪的是,图中的工具没有描述 3.) 共享父项 以允许用户确认其三向合并”,这很公平。 ;^) 没有颜色,它基本上描绘了一个毫无根据的合并。

标签: tfs merge


【解决方案1】:

您发布了 3 路合并工具的屏幕截图 - 我怀疑您将其归功于许多聪明才智。 TFS 使用任何 3 路合并工具来解决冲突 - 默认情况下,它包括图中的那个,但是您可以将其配置为使用 any 3-way merge tool of your choice

当 TFS 检测到冲突时(在这种情况下,是合并冲突,文件在两个分支中被编辑然后合并),它将尝试 automerge 文件的内容。如果无法自动合并,则需要您使用配置的 3 路合并工具来解决冲突。 TFS 只需将该工具提供 3 个路径:“source”(分支中的文件,即合并的源)、“target”(分支中的文件,即合并的目标)和“base”或 common祖先。

共同祖先是在两个分支之间合并的文件的最后一个版本。如果没有执行合并,则共同祖先是文件分支所在的变更集。在您第一次将更改从源合并到目标之前,情况将一直如此。例如,考虑 $/Main/A.txt 在变更集 2 处分支到 $/Branch/A.txt。如果在 $/Main/A.txt(作为变更集 3)上发生编辑,并且在 $/Branch/A.txt(作为变更集 4)上发生编辑,那么当您尝试合并时$/Branch$/Main,您将在 A.txt 上发生合并冲突。在这种情况下,共同祖先将是变更集 2(分支的版本。)

如果您要在合并工具中解决该冲突并检查结果(作为变更集 5),那么下次您从 $/Branch 合并到 $/Main 时,A.txt 的共同祖先将是变更集 5。(实际上,如果您在 TFS 冲突解决期间调用“比较源到基”或“比较目标到基”,您应该能够看到共同祖先及其版本信息。)

无论如何,一旦调用了合并工具,最终将由该工具负责提示您处理这些更改。工作流程依赖于工具,但典型的合并工具会逐行比较文件并将每一行标识为以下之一:

  • 未更改:源代码和目标代码中未更改的行
  • 共同的:从共同祖先改变的行,但完全相同
  • 冲突:源代码和目标代码都已更改且内容不同的行
  • Source only:仅在源中发生变化的行(目标与共同祖先相同)
  • 仅目标:仅在目标中发生变化的行(源与共同祖先相同)

如果存在冲突的行,则可以执行“自动合并”,这意味着通过从源中获取仅源行、仅目标行来修改共同祖先来自任一文件的目标和公共行以生成合并输出。 (如果可能,TFS 将把它作为“自动合并”选项提供。)

请注意,仅仅因为自动合并是可能的(并且通常在实践中有效),它与取行完全一样天真,并且不执行语法检查,因此您的 automerged output is not really what you want 可能是。

一些 3 路合并工具可能会提供一种模式,在该模式下它们会进行部分自动合并 - 默认情况下在打开时或在某些交互之后 - 采用公共、仅源和仅目标行,然后要求您解决手动冲突。

屏幕截图中的合并工具是与 Visual Studio ALM 捆绑的默认工具。 TFS 2012 中的工具比该版本显着改进。无论如何,third-party merge tool 可能会给您带来更好的体验。

请注意,尽管有标签,但合并工具实际上并不知道哪个文件按时间顺序更新。 (TFS 为合并工具提供标签以提供有关这些文件的一些上下文,合并工具只是将它们视为不透明的字符串。)“按时间顺序更新”也不一定是所有分支策略中的最佳合并策略。 (我在一个使用特性分支策略的团队中工作 - 我的特性分支具有相对较高的速度,我合并来自主分支的更改,该分支以相对较慢的节奏从所有特性分支中获取经过良好测试的更改。在这种情况下,年表相当不重要,无论如何我都需要合并我的冲突。

【讨论】:

  • 非常感谢您的回答。我非常了解合并工具的工作原理。但对我来说仍然是个谜的一件事是“共同祖先”是如何定义的。一旦我明白了,我就会理解我的合并工具产生的结果。在我的例子中,我们从 QA 分支创建了 Dev 分支。在该合并中,QA 是源,Dev 是目标。这是dev_histqa_hist 两个分支的签到历史记录)。哪个文件(变更集的版本)将用作“共同祖先”?
  • @davidoff 我对共同祖先的确定方式进行了一些扩展 - 我希望这更清楚一点?
  • 爱德华,你说的很清楚。尽管如此,它并不能解释我的情况。而且我很确定,一旦我分享更多细节,您就可以解释它。我隐藏了我们真正的分支结构。实际上我们有两个开发分支:HEAP 和 FP。它们是 QA 分支的子分支。 HEAP 是在变更集 30282 中创建的,FP 是在 chanset 30279 中创建的。(由于最大评论长度有限,我将转到另一条评论)
  • 我们在 FP 分支上工作,并在某些时候将 FP 分支的新功能反向集成到 QA 分支(更改集 30560)。现在我正试图将一个特定文件的更改拉到我的第二个开发分支(HEAP 分支)。而“共同祖先”应该是文件分支所在的变更集(因为我们从未在 HEAP 和 QA 之间合并该文件 - 如果我查看 HEAP 分支中文件的历史记录,我只会得到一个带有“分支”的条目改变类型)。但是当我使用三向合并工具时,它会将变更集 30560 显示为基本文件。你能解释一下为什么base是30560而不是30282吗?
【解决方案2】:

看起来您在此屏幕截图上遇到了合并冲突,对吧?

首先,不要使用Visual Studio/TFS 的合并工具,它真的没有效果,也不是很直观。使用免费的 KDiff3 或 Beyond Compare 以获得更好的自动合并和更用户友好的界面。

其次,据我所知,TFS 中的合并不存在时间连贯性(我可能错了,但我从未听说过)。您提到的两个变更集不在同一个分支中,因此 TFS 不关心哪个变更集发生在另一个之后以及它的含义。

第三,合并的方向不会从 branch1 到 branch2 或从 branch2 到 branch1 发生任何变化。唯一改变的是两个分支是否直接相关。

对我来说,您的问题主要是基于 GUI 的问题,或者您可能使用了自动合并功能,在发生冲突时根本不智能。

  1. 按照James Manning's post 更改您的合并工具
  2. 远离自动合并

【讨论】:

  • 谢谢,诺克。我尝试使用KDiff3。到目前为止,这对我来说有点不寻常,但我不得不承认,KDiff3 在合并操作期间确实提供了更多信息,并且更容易遵循合并逻辑。
  • 在阅读 Edward 的解释并查看“基本”文件后,很明显为什么结果将“Guid”(而不是“int”)作为参数类型。
【解决方案3】:

似乎 TFS 不支持间接集成,即从一个分支合并到另一个分支。您必须合并回父级,然后合并到您的其他分支(DEV)请参阅此帖子:http://social.msdn.microsoft.com/forums/en-US/tfsversioncontrol/thread/85c4ce74-59bc-4bec-a6e9-32b6e875a15a/

【讨论】:

  • 可以使用 baseless 选项强制间接合并,但它会忽略合并历史。由于最初的问题是关于间接合并(QA -> DEV),以及为什么 TFS 自动合并忽略了历史,所以答案仍然适用。
猜你喜欢
  • 2013-08-22
  • 2011-04-16
  • 2017-09-10
  • 2019-10-11
  • 2012-04-04
  • 2012-09-01
  • 2016-03-03
  • 2017-09-28
  • 2017-09-15
相关资源
最近更新 更多