简体   繁体   English

Git从分支同步分支

[英]Git syncing branches from branches

Let's say I've created a branch "B" off of an old tag from "A". 假设我已经从“ A”的旧标记创建了分支“ B”。 I make some changes on "B" and open a pull request back against "A". 我对“ B”进行了一些更改,并向“ A”打开了一个拉回请求。 I then make a "C" branch off of "B", which I make changes to and open a pull request, etc, until I reach branch "E". 然后,我从“ B”创建一个“ C”分支,然后对其进行更改并打开拉取请求等,直到到达分支“ E”为止。

Once I finish with my changes on "E", let's say all of these branches still have open, unmerged pull requests against "A". 我完成对“ E”的更改后,可以说所有这些分支仍然具有针对“ A”的未合并合并的拉取请求。 Since these could then be merged in any order, and "E" may have made some important changes to my original changes in"B", how do I ensure "B" has the changes from "C, D, E"; 由于这些内容可以按任何顺序合并,并且“ E”可能已对我在“ B”中的原始更改进行了一些重要更改,因此如何确保“ B”具有从“ C,D,E”开始的更改; "C" has the changes from "D, E"; “ C”具有与“ D,E”相比的更改; and "D" has the changes from "E". “ D”具有与“ E”相比的更改。

Let's assume I needed to go back and make changes to A prior to any pull requests being merged, but it relied on certain changes from E. 假设我需要返回并在合并任何拉取请求之前对A进行更改,但是它依赖于E中的某些更改。

A -----
 \
  B -----
   \
    C -----
     \
      D -----
       \
        E -----

The way you have drawn it, C has all B plus some, D has all C plus some, and E has all D plus some, so when you merge E into A , you get all of D , C , and B into A , so A will have it all. 绘制方式, C具有所有B加一些, D具有所有C加一些,并且E具有所有D加一些,因此,当将E合并为A ,会将DCB合并为A ,所以A将拥有全部。

If you say that you can merge any of B , C , D or E , in any order and ask "How will Git know what commits to merge each time"? 如果您说可以按任何顺序合并BCDE中的任何一个,并询问“ Git如何知道每次合并什么提交”? Well, that's one of the the big ideas of git merge - git will go back and realize what has already been merged in and won't try to remerge those changes. 好吧,这是git merge的重要思想之一-git会回过头来意识到已经被合并的内容,并且不会尝试重新合并这些更改。 For instance, if you merge B , which is composed of B1 , B2 , and B3 and then merge C (which is composed of C1 , C2 , C3 + B ( B1 , B2 , B3 )), then git looks at the merge history and finds all the commits that are already reached from the merge point and finds the ones that are not reached and merges those that are not reachable - that's how it knows what to merge (in this case, it would be C1 , C2 , C3 since it finds that B1 , B2 , B3 are reachable). 举例来说,如果合并B ,它是由B1B2B3 ,然后合并C (其由C1C2C3 + BB1B2B3 )),然后GIT中着眼于合并历史并找到从合并点已经到达的所有提交,找到未到达的提交,然后合并那些无法到达的提交,这就是它知道要合并的内容(在这种情况下,它将是C1C2C3因为发现B1B2B3可达)。 So, internally, for instance, if you have already merged B into A and then tell it to merge C into A , git identifies the un-merged commits by doing something like git rev-list C --not A and merges those commits.The key to understanding this is to think about it like a graph and realize that git is simply trying to figure out which parts of the graph are not reachable from the merge point and the branch to be merged and those are the changes that it then wants to merge in. 因此,在内部,例如,如果您已经将B合并为A ,然后告诉它将C合并为A ,则git通过执行git rev-list C --not A类的操作来标识未合并的提交,然后合并这些提交。理解这一点的关键是像一个图一样思考它,并意识到git只是试图从合并点和要合并的分支中找出该图的哪些部分是不可达的,而这些是它随后想要的更改合并。

If you continue on B (with B4 ) after the merge of B , that's fine, you can simply remerge branch B and it will take in just the new changes from B onto A because it does that graph traversal that I just described and realizes that B1 , B2 , and B3 have already been merged, and now its just this new B4 that it needs to merge. 如果您在合并B之后继续使用B (使用B4 ),那很好,您可以简单地重新合并分支B ,它将只接受从BA的新更改,因为它执行了我刚刚描述的图遍历并意识到B1B2B3已经合并,现在只是它需要合并的这个新B4

The typical lifecycle of a branch created from a parent branch is that the former ends up getting merged back into the parent at some point. 从父分支创建的分支的典型生命周期是,前者最终会在某个时候合并回到父中。 This concept is not limited to Git, but to development workflow in general. 这个概念不仅限于Git,还包括一般的开发流程。

In your situation, if you follow this principle it immediately resolves your problem. 在您的情况下,如果遵循此原则,它将立即解决您的问题。 Here is your diagram, redrawn to be a bit more palatable: 这是您的图表,重新绘制后变得更加可口:

A -----
 \
  B -----
   \
    C -----
     \
      D -----
       \
        E -----

Following the principle of merging a branch back into its parent, the order of merging should be E into D , D into C , C into B , and finally B into A . 按照将分支合并回其父代的原则,合并的顺序应为EDDCCB ,最后是BA In each of these merges, there should ideally be no conflicts. 在这些合并中的每一个中,理想情况下都应该没有冲突。 If there are conflicts, they should not be due to the parent and branch stepping on each other's toes, ie both branches having worked on the same exact areas of a feature. 如果冲突,他们不应该由于母公司和分公司踩着对方的脚趾,即在功能完全相同的领域工作过两个分支。

If your development process might require that you need to bring in the changes from E into A before rolling up all the branches in between, then you should reconsider how you create branches. 如果您的开发过程可能需要先将 E中的更改引入A中,然后再汇总它们之间的所有分支,那么您应该重新考虑如何创建分支。 In this case, you would have been better of creating branches A through E directly from the parent branch. 在这种情况下,最好直接从父分支创建分支AE

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

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