Subversion 分支合并实用指南
前言
我意识到 StackOverflow 上已经有很多关于合并 SVN 分支的问题。我已经阅读了其中的许多内容,但仍然没有真正找到我正在寻找的信息,因此请完整阅读此问题,然后再建议将其作为重复项关闭。
我需要将一个 SVN 分支合并到另一个分支。我对分支和合并的理论非常满意,但我一直在执行合并的实践中遇到困难,更具体地说,在识别和解决冲突方面。我怀疑这个问题的根本原因是我对完成工作所需的工具缺乏了解,即TortoiseSVN和各种可用的可视化合并工具。
根据阅读各种相关的 StackOverflow 问题,我确定了 Sourcegear DiffMerge 和 Beyond Compare 作为执行三向合并的候选工具。我尝试过 DiffMerge,但很难有效地使用它。我希望在解决冲突时看到以下三个文件
- 来自分支 A 的
- 文件 来自分支 B 的文件
- 执行合并的结果
但我看到的是
- 来自分支 A 的文件
- 来自分支 B 的文件
- A 和 B 的共同祖先,AKA 基础修订版
这导致我想知道在视觉上解决冲突时我采取的每个操作后如何看到合并的结果。我也很难实际执行这样的操作,例如,接受来自分支 A 或 B 的特定更改。在阅读了有关该主题的更多内容后,现在看来基本修订版实际上是合并结果的地方应该显示,这是正确的吗?
我认为演示使用 TortoiseSVN 和可视化合并工具合并分支的截屏视频或视频教程可能会回答我关于如何有效使用这些工具的大部分突出问题。我对解决执行合并本身的冲突的过程更感兴趣,但如果两者都被涵盖的话那就太好了。
Preface
I realise there are already a lot of questions about merging SVN branches on Stack Overflow. I have read many of them, but still haven't really found the information I'm looking for, so please read this question in it's entirety before proposing to close it as a duplicate.
I need to merge one SVN branch into another. I'm pretty comfortable with the theory of branching and merging, but I've always struggled with the practice of performing the merge, more specifically, with identifying and resolving conflicts. I suspect the root cause of this problem is a lack of understanding on my part of the tools required to get the job done, that is, TortoiseSVN and the various visual merging tools that are available.
Based on reading various related Stack Overflow questions, I've identified Sourcegear DiffMerge and Beyond Compare as candidate tools for performing the three-way merge. I tried DiffMerge, but struggled to use it effectively. I expected to see the following three files while resolving conflicts
- File from branch A
- File from branch B
- Result of performing the merge
But instead what I see is
- File from branch A
- File from branch B
- Common ancestor of A and B, AKA base revision
This led me to wonder how I can see the result of the merge after each action I take when resolving conflicts visually. I also struggled to actually perform such action, for example, accepting a particular change from either branch A or B. After reading about the subject a bit more, it now seems that the base revision is in fact the place where the results of the merge should be shown, is that correct?
I think a screencast or video tutorial that demonstrates merging branches with TortoiseSVN and a visual merge tool would probably answer most of my outstanding questions about how to use these tools effectively. I'm more interested in the process of resolving conflicts that performing the merge itself, but it would be great if both were covered.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
实际上,有两路和三路合并工具。双向应显示三个窗口。源分支版本A、目标分支版本B和合并结果。除此之外,三向合并还将显示基本版本。您可以将三路合并排序想象为 Result = Target + ( Base - Source ) 的等式。实际上,该算法将计算基础和源之间的一组差异以及基础和目标之间的另一组差异,然后剔除两者共有的所有差异。然后它会向您显示剩余差异列表以供决策。对于源或目标中的差异,其中同一代码段在其他分支中不受影响,它将自动预先决定使用适当的差异。如果差异位于两个分支中的同一代码部分,则差异将被标记为冲突,您的工具通常会引导您一一解决冲突。冲突不是预先决定的,并且在您做出决定之前,代码不会出现在结果文件中。您可以选择跳到下一个差异或下一个冲突。所有的冲突都必须由你来决定。根据您的知识,有时您希望回滚(重新决定)甚至不冲突的差异以完成合并。
因此,合并文件的过程基本上是逐一遍历差异或仅通过冲突差异来加速,并决定是否进行源分支更改、目标分支更改或编辑相关代码以创建新的合并更改。您所做的更改应该出现在结果窗口中,一旦确定了所有冲突,该工具应该允许您保存结果,然后该结果将成为目标分支上的新版本。包含基本文件的窗口通常仅显示作为参考,作为既没有源也没有目标更改的版本。
有些工具允许所谓的自动合并。如果没有冲突的差异,该工具将使用预先确定的差异解决方案,而不询问您任何问题。本质上自动获取源分支和目标分支的所有更改。虽然从词汇上来说这些变化并不冲突,但它们在其他方面仍然可能发生冲突。生成的代码可能无法编译或逻辑上不正确。但没有任何合并工具可以决定这一点。这就是为什么合并结果应该由人读取和审查,然后在提交到目标分支之前编译并通过测试套件运行。
Actually, there are two-way and three-way merging tools. A two-way should show three windows. The source branch version A, the target branch version B and a result of the merge. A three-way merge will show the base version in addition to that. You can imagine a three way merge sort of as equation of Result = Target + ( Base - Source ). In effect the algorithm will compute set of diffs between base and source and another set between base and target, then strike out all the diffs common to both. Then it will show you a list of remaining diffs for decision. For diffs in either source or target where the same section of code is not affected in the other branch, it will automatically pre-decide to use the appropriate diff. Where the diffs are in same section of code in both branches, the diffs are marked as a conflict and your tool will usually walk you through conflicts one by one. Conflicts are not pre-decided and the code will not appear in result file until you make a decision. You get option to skip to next diff or to next conflict. All conflicts must be decided by you. Based on your knowledge sometimes you want to roll back (re-decide) even non-conflicting diff in order to complete the merge.
So the process of merging a file is basically walking down through diffs or to speed up only through conflicting diffs one by one and deciding whether to take source branch change, target branch change or to edit the code in question to create a new merged change. The changes you do should appear in the result window and once you decide all conflicts, the tool should allow you to save the result, which will then become a new version on the target branch. The window with base file is usually shown only for a reference as a version that has neither a source or target change.
Some tools allow for so called automatic merge. In case there are no conflicting diffs, the tool will use the pre-decided diff resolution without asking you any questions. Esentially taking all changes from both source and target branch automatically. While lexically those changes do not conflict, they might still conflict in other ways. The resulting code might not compile or be logically correct. But no merge tool can decide that. That is why merge results should be read and reviewed by a human and then compiled and run through a test suite before being committed to the target branch.
您可以安装 KDiff3 来与 TortoiseSVN 执行三向合并。它自动与 Windows 平台上的 TortoiseSVN 集成。
它显示的三个文件是两个分支的共同祖先,即来自分支 A 的文件和来自分支 B 的文件。然后,您可以将冲突解决到表示要合并到的分支的文件中。
我发现它是一个非常智能的工具,在正常情况下会自动选择正确的选项来合并简单的冲突。
当它不确定时,它会问你该怎么做。
我有时会遇到问题,它选择了错误的方式。但在这些情况下,分支/合并路径相当复杂。
而且,正如 GrayWizard 所说,有时查看原始文件更容易。 Subversion 将在您要合并到的分支中生成一个原始文件,并带有标记来显示哪些更改来自哪个版本。我曾经有一两次需要在 IDE 中打开该文件并从那里修复它。
You can install KDiff3 to perform a three-way merge with TortoiseSVN. It automatically integrates with TortoiseSVN on the Windows platform.
The three files it shows you are common ancestor of both branches, file from branch A and file from branch B. You then resolve the conflicts into the file that represents the branch that you are merging TO.
I find that it is a very intelligent tool, and will in normal cases automatically choose the correct option for merging simple conflicts.
When it is not sure, it will ask you what to do.
I have on occasion had issues where it chose the wrong way around. Those were occasions where the branch/merge path were quite complex though.
And, as GrayWizard said, sometimes it is easier to look at the raw file. Subversion will product a single raw file in the branch that you are merging to with markup in showing you which changes were from which revision. I have once or twice needed to open that file in my IDE and fix it from there.
Perforce 有一个合并工具,可以显示所有四个版本(base、A 、B 和合并),并会直观地向您展示合并的样子。
在进行复杂的合并时,我实际上发现仅查看原始文件(假设它不是字节数据)并自己比较修订片段很有帮助。如果您的合并非常复杂(即重叠合并、移动代码等),这很可能是唯一的方法。
我见过的另一件事是导出工作集的一个副本,然后使用并排工具手动合并(例如 超越比较),然后直接签入。
关于合并总是让我困惑的一件事是它们与我预期发生的情况背道而驰。这总是给我带来基础修订版的问题。
Perforce had a merge tool which would show you all four versions (base, A, B and merge) and would show you visually what your merge would look like.
When doing complex merges, I actually find it helpful to just look at the raw file (assuming it's not byte data) and compare the revision pieces myself. If your merge is very complicated (that is, overlapping merges, moved code, etc.) this may well be the only way to do it.
One other thing I have seen done is to export one copy of the working set and then to manually merge using a side-by-side tool (like Beyond Compare) and then just do a straight check-in.
The one thing that always threw me about merges was that they were backwards from what I expected to happen. This always caused me problems with the base revision.