4

情况如下:需要将上游代码库(从V1到V2)的更改合并到从V1派生/分支的第三代​​码库S1中,以产生新的代码库S2。

我们可以访问 V1 和 V2 之间的日志和修订版本控制,以及 V1、V2 和 S1 的源。但是,S1 没有提供版本控制存储库和历史记录:不可能将其视为分支和进化主干之间的合并,因为从 V1 到达 S 的中间更改不是单独知道的。

情况是我们因此正在执行增量 3 路合并以生成 S2,并更新在 S1 中派生的更改以在 V2 的基础上工作。(我们不断发展的 V2 自然受到版本控制)

我发现 WinMerge 可用于识别目录结构之间完全不同/丢失/添加的文件,而 p4merge 在文件级别是一个很好的 3 路合并工具。

您建议使用哪些工具和技术?值得注意的是,代码库的规模很大,V1 和 V2 之间的中间修订数量很大,V1 和 S 之间的更改规模也很大。

4

5 回答 5

1

就个人而言,虽然可能不像前面提到的克隆检测器那么花哨,但我会从使用 开始diff -u S1 V1 >/tmp/diffs.patch,它应该告诉你 S1 中发生了什么变化。我怀疑很大比例的差异可以合并到 V2 与patch -p0 </tmp/diffs.patch. 任何它不能修补的地方都会尽可能多地修补,而被拒绝的更改则留给手动合并。

这应该在几分钟内处理所有“简单”的部分。您可能想试运行它,然后从 .patch 文件中删除一些棘手的文件,您将通过 3 路合并手动完成所有合并。

如果更改过于广泛(大规模重构或在文件之间移动大量代码),那么您可能需要使用 Ira 提到的工具。

于 2010-10-23T00:28:01.853 回答
0

您想知道的是 V2 和 S1 之间的增量,以及它们在哪里。

Winmerge 告诉您文件完全相同,或者它们是否丢失或不同。如果不同,它不会告诉你它们有什么共同点,如果有什么是合并的基础的话。

我会在 V2 和 S 中使用(我们的)克隆检测器来找出它们在语言结构粒度上的共同点。从 V2 克隆到 S 到同一文件中的代码块在某种意义上“已经合并”;如果将 V2 克隆到 S 中的不同文件中,则可能存在代码移动。如果存在可参数化的差异,克隆检测器(至少是我们的)将能够告诉您参数(“编辑”)是什么,您可以决定如何合并它们。在代码非常不同的地方,克隆检测器不会说任何东西,但是您可以通过从 Winmerge 所说的不同的文件中减去克隆检测器所说的主要是克隆的文件来获得该列表。这些非常不同的文件可能很难合并。

对于大部分是彼此克隆的文件,您可以使用我们的Smart Differencer告诉您如何修改 V1 文件以生成 S;这将提供细粒度变化信息。

于 2010-10-12T01:32:55.897 回答
0

如果 V 不在一个好的 VCS 中,那么将 V 导入到一个全新的 VCS 中开始可能是值得的。然后在 V1 创建一个分支,并导入您可以从备份、旧构建树、工作副本等中找到的每个 S1 旧副本。在 VCS 中尽可能多地构建从 V1 到 S1 的历史记录。如果有人在此过程中进行了一些剧烈的重新格式化,则可以通过将相同的工具应用于 V2 分支的修订来使其正常化。

然后使用合并工具解决冲突。如果有很多(并且可能会有),您可能希望在 V1..S1 和 V1..S2 历史的各个阶段逐步合并,以便您可以提交中间工作。

于 2010-10-23T00:36:03.917 回答
0

我真的推荐Beyond Compare。它有一个干净的 GUI、强大的比较算法、3 文件比较、目录结构比较等等。

于 2010-10-23T20:33:44.170 回答
0

您应该使用 Git 进行合并。签出 S1,然后 git merge v2。

如果 S1 在它和 V1 之间有很多变化,你可以确定重命名等会引发最少的冲突。或者,您可以在 s1 之上从范围 v1 到 v2 或在 v2 之上从范围 v1 到 s1 重新设置(重放更改) - 这取决于您想要达到的目标。这不是真正的 3 路合并。

如何将 v1..v2 和 v1..s1 历史记录到 git 中取决于您。如果不存在迁移工具,则应在每个修订版中编写导出脚本。然后只需在您使用的 SCM 中将您的结果作为 S2 提交到 S1 之上。

希望这可以帮助,

如果您需要我的帮助,或者还有其他一些非常擅长合并事物的人,您可以在#git irc 频道上找到我。

于 2010-10-23T00:55:44.823 回答