TFS:合并回主分支

Posted

技术标签:

【中文标题】TFS:合并回主分支【英文标题】:TFS: Merging back into main branch 【发布时间】:2010-11-28 21:28:10 【问题描述】:

我们有一个 Current 分支,主要开发发生在这里。一段时间以来,我一直在一个单独的分支中进行某种实验性的工作。换句话说,我将我需要的内容从 Current 分支分支到了 Experimental 分支。在工作期间,我经常将 Current 合并到 Experimental 中,这样我就有了其他人所做的更改,这样我就可以确定我所做的工作是否适用于他们的更改。

我现在想合并回 Current。首先,我将 Current 合并到 Experimental,编译并确保一切正常。所以在我看来,Experimental 和 Current 应该是“同步的”。但是当我尝试将 Experimental 合并回 Current 时,我遇到了一大堆冲突。但是当我将 Current 合并到 Experimental 时,我认为我已经解决了这些问题。

发生了什么事?我完全误解了什么吗?我怎样才能顺利地做到这一点?真的不想经历所有这些冲突...

【问题讨论】:

【参考方案1】:

当您在单个冲突上单击“解决”时,摘要消息会说什么?如果您从 Current -> Experimental 的合并是在没有大量手动工作的情况下完成的,则它应该类似于“X 源,0 目标,Y 两者,0 冲突”。换句话说,目标(当前)文件中没有不在源分支副本(实验)中的内容块。您可以安全地使用 AutoMerge All 按钮。

注意:AutoMerge 应该无论如何都是安全的。它被优化为对早期警告保守,而不是为了解决每个案例的能力。但我认识到我们中的许多人——包括我自己——喜欢在有任何问题时启动合并工具。在所描述的情况下,IMO,即使是最胆小的人也可以高枕无忧。


为什么会有冲突?如果摘要消息不是那么简单干脆怎么办?很高兴你问:) 简短的回答 - 因为确定相关文件的共同祖先(“基础”)的计算在很大程度上取决于它们之间的先前合并冲突是如何解决的。简单例子:

    设置两个分支,A 和 B。 在文件的不同部分对 A\foo.cs 和 B\foo.cs 进行编辑 合并 A -> B 自动合并冲突 合并 B -> A

TFS 必须将此事件序列标记为冲突。 B\foo.cs;4 和 A\foo.cs;2 之间最接近的共同祖先一直追溯到第 1 步,从那时起双方明显发生了变化。

在第 4 步之后很容易说 A 和 B 是同步的。(更准确地说:第 5 步合并的共同祖先是版本 #2)。当然,成功的内容合并意味着 B\foo.cs 包含迄今为止所做的所有更改?不幸的是,有很多原因你不能这样假设:

一般性:并非所有冲突都可以自动合并。您需要适用于这两种情况的标准。

正确性:即使 AutoMerge 成功,它也不总是生成有效代码。当两个人将相同的字段添加到类定义的不同部分时,就会出现一个经典示例。

灵活性:每个源代码管理用户都有自己喜欢的合并工具。他们需要能够在最初的 Resolve 决定 [“总有一天需要以某种方式合并内容”] 和最终的 Checkin [“在这里,这行得通”] 之间继续开发/测试。

架构:在像 TFS 这样的集中式系统中,服务器只能信任自己的数据库 + API 的验证要求。只要输入符合规范,服务器就不应尝试区分如何执行各种类型的内容合并。 (如果您认为到目前为止的场景很容易区分,请考虑:如果 AutoMerge 引擎有错误怎么办?如果流氓客户端直接使用任意文件内容调用 Web 服务怎么办?这里只是触及表面......服务器必须持怀疑态度是有原因的!)它可以安全地计算出来的是您向我发送了一个与源或目标不匹配的结果文件

将这些要求放在一起,您最终得到的设计将我们在第 4 步中的操作归为一个相当广泛的类别,其中还包括由重叠编辑产生的手动合并、由第 3 方工具提供的内容合并 [自动或非自动],以及事后手工编辑的文件。在 TFS 术语中,这是一个AcceptMerge 解决方案。一旦如此记录,为了追求历史完整性和未来运营的安全性,合并规则 (tm) 必须假设最坏的情况。在此过程中,您对第 4 步的语义意图(“将 #2 中对 A 所做的每个更改都完全纳入 B”)被简化为几个字节的纯逻辑(“给 B 以下新内容 + 处理的功劳# 2")。不幸的是,这“只是”一个用户体验/教育问题。当合并规则做出导致代码损坏和数据丢失的错误假设时,人们会变得更加愤怒。相比之下,您所要做的就是单击一个按钮。

FWIW,这个故事还有很多其他的结局。如果您在第 4 步中选择了从源分支复制 [aka AcceptTheirs],则在第 5 步中不会发生冲突。如果您选择了 AcceptMerge 解决方案但碰巧提交了与 A\foo.cs;2 具有相同 MD5 哈希的文件,则同上.如果您改为选择 Keep Target [aka AcceptYours],则下游后果会再次发生变化,尽管我现在不记得细节了。当您添加其他更改类型(尤其是重命名)、合并比我的示例更不同步的分支、挑选某些版本范围并稍后处理孤儿等时,上述所有内容都会变得相当复杂......


编辑:就像命运一样,其他人刚刚在 MSDN 论坛上问了完全相同的问题。由于往往是我的本性,我给他们写了另一个完全不同的长答案! (虽然显然触及相同的关键点)希望这会有所帮助:http://social.msdn.microsoft.com/Forums/en-US/tfsversioncontrol/thread/e567b8ed-fc66-4b2b-a330-7c7d3a93cf1a

【讨论】:

哇,很好的透彻的解释。不确定我是否完全理解了这一切,但我想这就是为什么我不在 TFS 团队中的原因:P 无论如何,这并不像我想要的那样简单:PI 最终不得不经历所有这些.其中一些是重命名冲突,我只是被要求选择一种替代方案。其他的稍微复杂一些。但它现在似乎正在工作:) 我发布了另一个解释,希望能减少混淆:)【参考方案2】:

我以前也遇到过这种情况。当 TFS 将 Experimental 合并到 Current 时,它会使用硬盘驱动器上的工作区。如果您的当前工​​作区在本地计算机上已过期,则 TFS 将出现合并冲突。

(在 HD 上进行实验)!=(TFS 中的当前版本)!=(HD 上的旧版本)

尝试强制获取 Current 以刷新本地的 Current 副本并再次尝试合并。

【讨论】:

试过了,但似乎没有任何帮助。 猜对了,不过。这肯定会导致像 Svish 的症状。【参考方案3】:

在开始合并之前你可能有这样的行...

主分支 - 包含代码 A、B、C 当前分支 - 包含代码 A、B、C、D、E 实验分支 - 包含代码 A、B、C、D、F、G、H

当您从 Current 推送到 Exp 时,您正在将功能 E 合并到实验分支中。

当您随后从 Exp 推送到 Current 时,您仍然必须合并 F、G 和 H。这可能是您的冲突的根源。

----对第一条评论的回应---- 您是自动合并还是使用合并工具? 什么是“冲突”的例子?

【讨论】:

我只有两个分支。而且,为了继续您的示例,我已经将 Current 合并到 Experimental 中,因此 Experimental 也包含 E。所以应该没有冲突,只有新代码。如果这有任何意义...... 尽可能自动合并,但并非总是如此。

以上是关于TFS:合并回主分支的主要内容,如果未能解决你的问题,请参考以下文章

如何将分支合并回主分支并避免树冲突 - TortoiseSVN

TFS:在两个分支之间合并 .csproj 文件,两个分支之间有项目引用

TFS 中的跨分支合并?

防止在 TFS 2017 分支上直接签入,仅允许合并

如何在 TFS 中分支和合并

TFS 获取分支 -> 回滚 -> 向后合并并希望删除所有更改