简体   繁体   English

从分支分支,重新整合合并和mergeinfo

[英]Branch from branch, reintegrate merge and mergeinfo

I have a branch A started from trunk and a branch B started from A. Periodically, a merge from trunk to A is made and later a merge from A to B is also performed. 我有一个从主干开始的分支A和一个从A开始的分支B。定期进行从主干到A的合并,然后再执行从A到B的合并。 When I want to merge A and B to trunk, I think to follow this way: 当我想将A和B合并到主干时,我想遵循这种方式:

  • reintegrate merge from B to A 从B重新合并到A
  • reintegrate merge from A to trunk 从A重新整合合并到主干

Is it correct? 这是正确的吗? Or can it cause problem to mergeinfo or other problems? 还是会引起合并信息问题或其他问题? What is the best practice in this case? 在这种情况下,最佳做法是什么?

Subversion has been (sometimes unfairly) criticized for bad merging. Subversion因合并不当而受到批评(有时是不公平的)。 In truth, Subversion is really good at merging. 实际上,Subversion确实擅长合并。 To understand what you need to do, you need to understand how Subversion does merging. 要了解您需要做什么,您需要了解Subversion如何合并。

Subversion normally, sort of (which I'll explain later) does a standard 3-way merge. 通常,Subversion会执行标准的三向合并(稍后将进行解释)。 It compares the two files being merged to the last ancestor those two files shared. 它将两个文件合并到共享的最后一个祖先。 That way, it can tell what changes in the file came from the branch it is on, and what changes came from the other branch. 这样,它可以判断文件中的哪些更改来自它所在的分支,以及哪些更改来自另一个分支。

Because Branch "B" comes from Branch "A" which came from trunk. 因为分支“ B”来自于主干的分支“ A”。 You can merge from trunk to B or trunk to A. These merges should work just fine. 您可以从主干到B或从主干到A合并。这些合并应该可以正常工作。 If you are merging a particular set of changes from wither Branch B or Branch A to trunk or to the other branch, everything should work just fine. 如果您要合并从分支B或分支A枯萎到主干或另一个分支的一组特定更改,那么一切都应该很好。

Now, I said (sort of) does a standard 3-way merge . 现在,我说(某种程度上)执行标准的3路合并 Subversion was written to allow you to specify specific set of changes you made in one branch to merge with the other. 编写Subversion是为了允许您指定在一个分支中进行的特定更改集,以与另一个分支合并。 When you merge, Subversion doesn't look at the file you're merging, it starts with the base, the last common ancestor, then applies those changes that are being considered for the merge. 合并时,Subversion不会查看要合并的文件,它从基础(最后一个共同祖先)开始,然后应用为合并考虑的那些更改。 Under these circumstances, when you specify exactly what you want to merge, Subversion does a wonderful job of merging. 在这种情况下,当您确切指定要合并的内容时,Subversion会完成出色的合并工作。

Therefore, if you are specifying that Branch "A" has a particular change and you want to merge this change to Branch "B" or to the trunk, Subversion does a wonderful job at merging. 因此,如果您指定分支“ A”具有特定更改,并且希望将此更改合并到分支“ B”或主干,则Subversion在合并方面做得很好。

Things started changing in Subversion 1.5 when Subversion started tracking repository revisions that were previously merged into a branch or trunk. 当Subversion开始跟踪先前合并到分支或主干中的存储库修订时,Subversion 1.5中的情况开始发生变化。 This prevented me from merging changes previously merged into the branch, but it also allowed me to be lazy. 这阻止了我合并以前合并到分支中的更改,但是这也使我变得懒惰。 There's nothing wrong with being lazy. 懒惰没有错。 I highly endorse it. 我高度赞同。

Imagine I make a feature branch at revision 100 from trunk. 想象一下,我在主干的修订版100中创建了一个功能分支。 I make the branch at revision 100. Let's say this is a list of the revisions made in my repo: 我在版本100处创建了分支。假设这是我的仓库中所做的修订的列表:

  • Branch : 103 105 108 分行 :103105108
  • Trunk : 101 102 104 105 106 107 行李箱 :101102104105106107

When I merge from trunk to my feature branch, and I don't specify what revisions I want to merge, Subversion does the cherry picking for me. 当我从主干合并到功能分支时,并且没有指定要合并的修订版本,Subversion会为我完成任务。 It knows the last common ancestor was revision 100. It then looks and sees that the changes on trunk of revision 101, 102, 104, 105, 106, and 107 have not been applied to my branch. 它知道最后一个共同祖先是修订版100。然后,它看到并发现修订版101、102、104、105、106和107的主干上的更改尚未应用于我的分支。 It then cherry picks these specific changes and merges them to my branch. 然后樱桃选择这些特定的更改并将它们合并到我的分支中。

  • Branch : 103 105 108 109 分行103105108109
  • Trunk : 101 102 104 105 106 107 行李箱 :101102104105106107

Revision 109 is the result of my merge. 修订版109是我合并的结果。 To track the changes, Subversion puts onto Revision 109 a svn:mergeinfo property that says trunk:101-107 have been merged onto the branch:. 为了跟踪更改,Subversion在修订版109上添加了一个svn:mergeinfo属性,该属性表示trunk:101-107已合并到分支:上。 Lets do more work: 让我们做更多的工作:

  • Branch : 103 105 108 109 110 111 分支 :103 105 108 109 110 111
  • Trunk : 101 102 104 105 106 107 112 113 行李箱 :101102104105106107112113

I want to merge from my trunk onto my branch again. 我想再次从树干合并到分支。 If I wasn't lazy, I would specify I want revisions 112 and 113 merged onto my branch. 如果我不偷懒,我会指定我要将修订版112和113合并到我的分支中。 However, being lazy, I let Subversion do the work. 但是,由于懒惰,我让Subversion完成了工作。 Subversion sees from svn:mergeinfo that all trunk revisions from 101 to 107 have already been merged into my branch. Subversion从svn:mergeinfo看到,所有从101到107的主干版本都已经合并到我的分支中。 Therefore, Subversion picks revisions 112 and 113 for me: 因此,Subversion为我选择了修订版112和113:

  • Branch : 103 105 108 109 110 111 114 分支 :103 105 108 109 110 111 114
  • Trunk : 101 102 104 105 106 107 112 113 行李箱 :101102104105106107112113

And Subversion creates revision 114, and sets svn:mergeinfo to say that all changes on trunk from revision 101 to revision 113 have been merged onto my branch. 然后Subversion创建了修订版114,并设置svn:mergeinfo表示从修订版101到修订版113的主干上的所有更改都已合并到我的分支中。

Now, I have finished my feature, and I want to merge all of my changes I made on my branch back onto my trunk. 现在,我已经完成了功能,我想将在分支上所做的所有更改合并回我的主干。 If I was not such a lazy bum, I would specify that I want revisions 103, 105, 108, 110, and 111 to be merged onto my trunk. 如果我不是那么懒惰,我会指定我希望将修订版103、105、108、110和111合并到我的主干上。 If I did this, there's absolutely no problem at all. 如果我这样做了,那绝对没有问题。 Subversion does a wonderful job with the merge. Subversion在合并方面做得很好。

Note I didn't specify that I wanted changes 109 and 114 merged (the two changes in bold). 注意,我没有指定要合并的更改109和114(两个更改以粗体显示)。 Why? 为什么? Because those weren't changes on my branch, they were trunk changes I merged onto my branch. 因为这些不是我分支上的更改,所以它们是我合并到分支上的主干更改。 If I specified those two revisions, I would be reapplying my trunk changes back onto my trunk. 如果指定了这两个修订版,则将重新应用我的主干更改回我的主干。

But, I am lazy, and I want Subversion to do the work for me. 但是,我很懒,并且我希望Subversion为我完成工作。 Subversion looks at my branch, and sees all of those changes, including change 109 and 114, and wants to merge those onto my trunk. Subversion查看我的分支,并查看所有这些更改,包括更改109和114,并希望将其合并到我的主干中。 Not good. 不好。

So, Subversion does something special here. 因此,Subversion在这里做了一些特别的事情。 If we think of a file and the revisions as change sets to apply to a file, I am basically applying all the changes that took place on my trunk onto my branch and all those changes on my branch onto my trunk. 如果我们认为文件和修订是要应用于文件的变更集,则基本上是将我在主干上进行的所有更改都应用到分支上,而将所有在分支上进行的更改都应用到我的树干上。 In other words, when I finish this branch to trunk merge, my branch and my trunk will match. 换句话说,当我完成此分支到主干合并时,我的分支和主干将匹配。

This is what a reintegration merge does. 这就是重新整合合并的工作。 Unlike the normal merge where changes from my two files are compared to a base revision and then carefully applied, all changes on my branch will be applied to my trunk without comparing it to the base revision. 与正常的合并不同,常规合并将两个文件中的更改与基本修订进行比较,然后仔细应用,而分支上的所有更改都将应用于主干,而无需将其与基本修订进行比较。 The reintegration merge is a two way merge. 重新整合合并是两种方式的合并。 Any difference between the branch and the trunk will be overwritten. 分支与主干之间的任何差异都将被覆盖。

Let's look at what happens: 让我们看看会发生什么:

Before Reintegration Merge 重新整合之前

  • Branch : 103 105 108 109 110 111 114 分支 :103 105 108 109 110 111 114
  • Trunk : 101 102 104 105 106 107 112 113 行李箱 :101102104105106107112113

  • svn:mergeinfo on branch now says trunk:101-113 svn:mergeinfo的分支现在显示trunk:101-113

After Reintegration Merge 重新融合后

  • Branch : 103 105 108 109 110 111 114 分支 :103 105 108 109 110 111 114
  • Trunk : 101 102 104 105 106 107 112 113 115 行李箱101102104105106107112113115

  • svn:mergeinfo on branch now says trunk:101-113 svn:mergeinfo的分支现在显示trunk:101-113

  • svn:mergeinfo on trunk now says branch:103-114 svn:mergeinfo在树干上现在显示branch:103-114

Let's do more work on trunk just to show you what happens if I continue to use my feature branch. 让我们在中继上做更多工作,只是向您展示如果我继续使用功能分支会发生什么。 I'll put two more changes onto trunk: 我将在中继上再进行两个更改:

  • Branch : 103 105 108 109 110 111 114 分支 :103 105 108 109 110 111 114
  • Trunk : 101 102 104 105 106 107 112 113 115 116 117 外线 :101 102 104 105 106 107 112 113 115 116 117

  • svn:mergeinfo on branch now says trunk:101-113 svn:mergeinfo的分支现在显示trunk:101-113

  • svn:mergeinfo on trunk now says branch:103-114 svn:mergeinfo在树干上现在显示branch:103-114

Now, I want to merge these changes back to my feature branch. 现在,我想将这些更改合并回我的功能分支。 If I did the cherry picking myself, I would specify I want revisions 116 and 117 onto my branch because those were the two changes I just made. 如果我自己摘樱桃,我会指定我要对分支进行修订116和117,因为这是我刚刚进行的两个更改。 Again, if I was studious and hard working, Subversion merging would be fine. 再说一次,如果我勤奋好学,那么Subversion合并就可以了。 However, I'm lazy, and will let Subversion do the cherry picking. 但是,我很懒,将让Subversion进行摘樱桃。

Subversion looks at svn:mergeinfo and sees that I've applied changes 103 to 114 onto my branch. Subversion查看svn:mergeinfo并看到我已将更改103更改为114到我的分支上。 It now sees three new changes on my trunk: changes 115, 116, and 117. However, Change 115 is the result of my reintegration merge! 现在,它在我的主干上看到三个新更改:更改115、116和117。但是,更改115是我重新整合合并的结果! All of the changes in 115 are already on the branch. 115中的所有更改都已经在分支上。 Letting Subversion do the picking will lead to disaster. 让Subversion进行挑选将导致灾难。

This is why you're told not to reuse a branch once you reintegrated it. 这就是为什么告诉您在重新集成分支后不要重用它的原因。 The way around this is to do a svn merge --record-only -c 115 from trunk onto my branch. 解决此问题的方法是从主干到我的分支上执行svn merge --record-only -c 115 No merge will actually take place, but now Subversion will record that changes 101 to 115 are on my branch. 实际上不会进行任何合并,但是现在Subversion将记录101到115的更改在我的分支上。 If I did that, and then did a merge from trunk to branch, Subversion would skip over selecting change 115 and only do changes 116 and 117. 如果我这样做了,然后从主干到分支进行了合并,则Subversion将跳过选择更改115,而仅执行更改116和117。


Now that you understand how Subversion does merge tracking and what a reintegration merge is, we can look at your situation: 既然您了解了Subversion如何进行合并跟踪以及什么是重新整合合并,我们就可以看一下您的情况:

  • You branched from trunk to Branch A 您从树干分支到分支A
  • You branched from Branch A to Branch B 您从分支A分支到分支B
  • You merge from Trunk into Branch A 您从中继合并到分支A
  • You merge from Branch A into Branch B 您从分支A合并到分支B

If you are a hardworking young programmer who wakes up every morning at 5am to run 5 miles just to get you into the mood for work, you will specify what revisions from each branch you want to merge into the other branches or trunk. 如果您是一个勤奋的年轻程序员,每天早晨5点醒来奔跑5英里,只是为了让您有工作的心情,则可以指定要合并到其他分支或主干的每个分支的修订版本。 If you did this, there is no problem at all, you do the standard merge, and get ready for your daily 100 kilometer bike ride you do after a vigorous workout session at the gym. 如果您这样做了,那完全没有问题,您可以进行标准合并,并在健身房进行了充分的锻炼之后,准备好进行每天100公里的自行车骑行。

If you are a typical technical worker (ie, lazy) and you want Subversion to handle the selecting of the revisions for you, things are a bit different: 如果您是典型的技术人员(即懒惰的人),并且希望Subversion为您处理版本的选择,则情况会有些不同:

  • You merge all of your changes from Branch A into Branch B. Now, your branch B will include all revision on Branch A. 您将所有更改从分支A合并到分支B。现在,分支B将包括分支A上的所有修订。
  • You do a reintegration merge of branch B back into Branch A. Now all of your changes on Branch A and Branch B will be on both branches. 你做分支B的重返合并到分公司A.现在所有对支路A和支路B您的修改将在两个分支。
  • You do a regular merge of your trunk to Branch A. Branch A contains all of your changes you've made on Branch A. Plus, all of the changes on Branch B and trunk. 您将主干与分支A进行常规合并。分支A包含您在分支A上所做的所有更改。此外,还包含分支B和主干上的所有更改。
  • You do a reintegration merge of Branch A (which already contains your Branch B changes) onto trunk. 您将分支A(已经包含您的分支B更改) 重新整合到主干上。 Now Trunk, Branch A, and Branch B all contain the same set of changes, and all three should match. 现在,主干,分支A和分支B都包含相同的更改集,并且所有三个更改都应匹配。
  • You should now never use Branch A or Branch B again unless you do a svn merge --record-only to record that Branch B to Branch A reintegration change onto Branch B and that Branch A to trunk reintegration change onto Branch A. 现在,除非您执行svn merge --record-only记录分支B到分支A的重新集成更改到分支B以及分支A到主干的重新集成更改到分支A上,否则您永远不要再使用分支A或分支B。

Important Change in Subversion 1.8 Subversion 1.8的重要更改

Knowing whether to do a regular merge or a reintegration merge in Subversion can be a bit error prone. 知道在Subversion中执行常规合并还是重新合并合并可能会出现一些错误。 It's a manual process and something that could be a disaster if I, being a normal human being, make a mistake (which I will do at the very worst time). 这是一个手动过程,如果我作为一个普通的人犯了一个错误(在最糟糕的时候我会做的),这可能是一场灾难。

In Subversion 1.8, Subversion now tries to determine by looking at svn:mergeinfo which way you do your merging and when you have to do a reintegration merge. 在Subversion 1.8中,Subversion现在尝试通过查看svn:mergeinfo来确定您进行合并的方式以及何时必须进行重新集成合并。 Thus, you no longer have to specify the --reintegration flag on merging. 因此,您不再需要在合并时指定--reintegration标志。 Subversion will also make sure that if you reuse a branch after it was reintegrated into another branch or trunk, not to reapply the changes that took place during reintegration. Subversion还可以确保,如果在将分支重新集成到另一个分支或主干后重新使用它,则不要重新应用在重新集成过程中发生的更改。

If you like to do a lot of feature branching, you should use Subversion 1.8 which will handle a lot of the error proneness in merge tracking for you. 如果您想进行很多功能分支,则应使用Subversion 1.8,它将为您处理合并跟踪中的许多错误倾向。 If you are using Subversion 1.8, you should be able to do merges from Branch B to Branch A and into trunk without any problems. 如果您使用的是Subversion 1.8,则应该能够将分支B合并到分支A并合并到中继中,而不会出现任何问题。

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

相关问题 颠覆,从重新整合的合并中删除 MergeInfo 是否安全 - Subversion, is it safe to remove MergeInfo from a reintegrate merge Subversion修订版的合并信息分支 - Subversion branch from revision with mergeinfo 重新整合分支与合并一系列修订 - Reintegrate a branch vs merge a range of revision Subversion合并到分支不完整-合并信息损坏了吗? - Subversion merge to branch is incomplete - broken mergeinfo? svn-“一旦--reintegrate合并从分支到主干完成,分支将不再可用于进一步的工作。” - svn - “Once a --reintegrate merge is done from branch to trunk, the branch is no longer usable for further work.” cherrypick svn合并分支到trunk,然后合并--reintegrate? - cherrypick svn merge branch to trunk, followed by later merge with --reintegrate? svn:创建分支之前的mergeinfo条目 - svn: mergeinfo entries from before the branch was created 如何在SVN中重新合并具有损坏的合并历史记录的功能分支? - How do I reintegrate a feature branch with broken merge history in SVN? 重新合并缺少分支的合并声明,其中包含创建分支之前的数字 - Reintegrate merge claims missing revisions with numbers lying before branch creation Tortoisesvn Subversion 1.8 - 合并 - 不再重新整合分支选项 - Tortoisesvn Subversion 1.8 - merge - no more reintegrate a branch option
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM