简体   繁体   English

如何解决SVN树冲突

[英]How do I resolve a SVN tree conflict

I have been reading for days now trying to find a way to resolve tree conflicts using tortiseSVN 1.8. 我已经阅读了几天,试图找到一种使用tortiseSVN 1.8解决树冲突的方法。 I have two branch off of trunk: 我的主干有两个分支:

  • branches/3.1 分支/ 3.1
  • branches/3.2 支链/ 3.2

Again, both of these branches were off of trunk. 同样,这两个分支都不是主干。 We do not do "mainline" development on trunk. 我们不在主干上进行“主线”开发。 I'm trying to merge the changes from our 3.1 branch to our 3.2 branch. 我正在尝试将3.1分支的更改合并到3.2分支。

The code in 3.1 went through some refactoring and a lot of folders that exist in the 3.2 branch no longer exist in the 3.1 branch. 3.1中的代码经过了一些重构,并且3.2分支中存在的许多文件夹在3.1分支中不再存在。 Also, there is some new work adding new folder to 3.2. 此外,还有一些新工作将新文件夹添加到3.2。 The problem is that a tree conflict does not give me a way to resolve the conflicts, but only allows me to accept the working copy. 问题是树冲突没有给我解决冲突的方法,而只允许我接受工作副本。 This seems like a serious flaw. 这似乎是一个严重的缺陷。 We are doing a lot of refactoring and I'm looking for a process that we can integrate changes on an earlier release branch into a later release branch. 我们正在进行大量的重构,我正在寻找一个过程,可以将早期版本分支上的更改集成到以后版本分支中。

Can somebody tell me the best way to handle this? 有人可以告诉我最好的方法吗?

For merging to work, you need two things: 要进行合并,您需要做两件事:

  • You need a common ancestry between the two branches. 您需要两个分支之间有共同的血统。
  • If you place on keeping the two branches, in sync, you need to do regular merging between the two. 如果您将两个分支保持同步,则需要在两个分支之间进行常规合并。 For example, I assume that all work on 3.1 should be in 3.2. 例如,我假设所有在3.1上的工作都应该在3.2中。 As you do work in both branches, you should have been merging your 3.1 changes into 3.2. 在两个分支中都进行工作时,应该将3.1更改合并到3.2。

Merge conflicts happen because merging is a three-way comparison. 发生合并冲突是因为合并是一种三向比较。 The two development streams (a development stream can refer to a branch or trunk) are compared to each other, and they're compared to their last common ancestor. 将这两个开发流(一个开发流可以引用一个分支或主干)相互比较,并将它们与最后一个共同祖先进行比较。 Imagine a file where line #100 was changed in both development streams. 想象一个文件,在两个开发流中都更改了第100行。 A merge from one to the other will result in a conflict. 从一个合并到另一个将导致冲突。

Subversion doesn't just diff files, it diffs directories too. Subversion不仅可以比较文件,还可以比较目录。 If I rename a file in one development steam (or move it), and I do a merge, it will be renamed (or moved) in the other development stream. 如果我在一个开发流中重命名(或移动了一个文件)并进行了合并,则它将在另一个开发流中被重命名(或移动了)。 If I delete or add a file in one development stream, and merge, it will be deleted or added in the other development stream too. 如果我在一个开发流中删除或添加文件,然后合并,它也会在另一开发流中删除或添加。

In Subversion, a tree conflict can happen if I do two different things to the same file on the two development streams. 在Subversion中,如果我对两个开发流中的同一文件执行两项不同的操作,则可能会发生树冲突 For example, I rename the file on both the 3.1 and 3.2 branch. 例如,我在3.1和3.2分支上都重命名了文件。 Even if I rename them the same name, Subversion will pick it up as a conflict. 即使我使用相同的名称重命名,Subversion也会将其视为冲突。


To prevent your disaster from happening again: Make sure that your two branches do share the same ancestry. 为防止灾难再次发生:确保两个分支确实具有相同的血统。 Why not branch 3.2 from the 3.1 branch, or at least reintegrate the 3.1 branch back into trunk before branching 3.2. 为什么不从3.1分支中分支3.2,或者至少在分支3.2之前将3.1分支重新集成到主干中。 Subversion usually is pretty good at following history, but you need to make sure that the branches share a common history. Subversion通常非常擅长跟踪历史记录,但是您需要确保分支共享相同的历史记录。

The other is regular merging. 另一个是定期合并。 You need to merge 3.1 to the 3.2 branch on a regular basis -- maybe even every day. 您需要定期将3.1合并到3.2分支-甚至每天。 This makes sure that people working on the 3.2 branch have the changes they need in 3.1 and aren't duplicating the work. 这样可以确保在3.2分支上工作的人员在3.1中具有他们所需的更改,并且不会重复所做的工作。 Constant merging also keeps the changes small, and when there are merge conflicts they're much easier to handle. 持续合并还可以使更改保持较小,并且当存在合并冲突时,它们更容易处理。 Remember the svn mergeinfo command which can let you know what's already been merged into 3.2 and what on 3.1 still needs to be merged. 记住svn mergeinfo命令,该命令可以让您知道已经合并到3.2中的内容以及在3.1上仍然需要合并的内容。 You can always use the --record-only parameter to prevent a particular revision from being considered for a future merge. 您始终可以使用--record-only参数来防止将来的合并考虑使用特定的修订版。 For example, you fix a bug on both branches, you use --record-only to make sure that the fix on 3.1 isn't done on 3.2. 例如,您修复了两个分支上的错误,使用--record-only来确保对3.1的修复未对3.2进行。 Or, if you made a change in 3.1 you don't want on 3.2, doing a --record-only will prevent you from considering that change on the 3.2 branch the next merge. 或者,如果您在3.1中进行了更改,而您不想在3.2上进行更改,则执行--record-only将阻止您在下次合并时在3.2分支上考虑该更改。


What to do now? 现在做什么? You need to untangle your work. 您需要解开工作。 Look at a svn log between the two branches. 查看两个分支之间的svn log If you see a bugfix taking place on both branches, use a svn merge --record-only to let Subversion know that a particular change on the 3.1 branch was also done (albeit manually) on the 3.2 branch. 如果您看到两个分支上都发生了错误修复,请使用svn merge --record-only来让Subversion知道3.1分支上的特定更改也已在3.2分支上完成(尽管手动)。 Look at file moves and renames and see how they were done on each branch. 查看文件移动和重命名,以及如何在每个分支上完成它们。

Once you've done that, merge changes on 3.1 to 3.2 a few revisions at a time, cherry pick merges. 完成此操作后,一次将3.1到3.2的更改合并到几个修订版中,然后进行合并。 Make sure that a change on 3.1 is something you want on 3.2. 确保在3.2上需要对3.1进行更改。

This is a long draw out process, but you it needs to be done. 这是一个漫长的过程,但是您需要完成它。 Use this as a lesson to improve your development process. 将其用作改进您的开发过程的课程。


We use to use what sounds like a similar system you used. 我们曾经使用听起来像您所使用的类似系统的东西。 Trunk was suppose to be pristine and match our releases (it never really did). Trunk被认为是原始的,并且与我们的发行版相匹配(从来没有真正做到过)。 We kept losing changes from one release to another because of when we made a new branch and when we merged the previous branch to trunk (or we simply lost where we branched from). 由于创建新分支以及将先前的分支合并到主干(或者只是丢失了从何处分支),我们一直在丢失从一个版本到另一个版本的更改。

Branching is like children: You make one, and you better be ready to take care of it and not lose track where it goes. 分支就像孩子:您创造了一个分支,最好准备好照顾它,而不要迷失方向。

We switched to a continuous development process . 我们转向了持续发展的过程 We do our development on trunk, and then branch right before we do a release. 我们在主干上进行开发,然后在发布之前进行分支。 The branch point usually comes around the time when we finished all of the features for that release, and we are now in a process of bug fixing. 分支点通常在我们完成该版本的所有功能时出现,并且我们现在正在进行错误修复。

The release is done on the branch. 发布在分支上完成。 If we find a bug, we will fix the bug on the branch, and then only merge that revision to the trunk (if that bug is also on the trunk). 如果发现错误,则将在分支上修复该错误,然后仅将该修订合并到主干(如果该错误也在主干上)。 Once a release is done, the branch is locked. 发布完成后,分支将被锁定。 If we need to do a hotfix, we can reuse that branch for the hotfix. 如果我们需要做一个修补程序,我们可以将该分支重新用于该修补程序。

Occasionally, we have feature branches . 有时,我们有功能分支 When we do, I make sure that we are constantly merging from the development stream to that feature branch. 当我们这样做时,我确保我们不断地从开发流合并到该功能分支。 This way, when we finally reintegrate that feature back into trunk, we have few if any conflicts. 这样,当我们最终将该功能重新集成到主干中时,几乎没有冲突。

By keeping branching to a minimum and by tracking where we branch from, and doing constant merges (like in a feature branch), we have reduced merge conflicts, and no longer have the issues that once plagued our releases. 通过最小化分支并跟踪我们从何处分支,并进行恒定合并(如在功能分支中进行合并),我们减少了合并冲突,并且不再遇到曾经困扰我们发行版的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM