首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果其中一个功能分支合并到主功能分支,那么更新取自功能分支的姊妹子功能分支的最佳方式是什么?

如果其中一个功能分支合并到主功能分支,那么更新取自功能分支的姊妹子功能分支的最佳方式是什么?
EN

Stack Overflow用户
提问于 2018-10-26 19:31:43
回答 2查看 84关注 0票数 0

给定master -> AA->B1A->B2

如果B2合并到master中,那么更新B1的最佳方式是什么

我正在尝试理解合并分支层次结构方面的最佳实践。

什么是可接受的,什么是不能接受的(例如,什么可能导致合并冲突或混乱的GitHub文件更改选项卡)

什么时候按顺序合并是有意义的,什么时候直接合并是有意义的,无论是特征分支向后向主还是向后向特征分支,还是特征分支之间的分支?

EN

回答 2

Stack Overflow用户

发布于 2018-10-26 19:51:34

我不确定我是否理解正确,但我认为你是在问这种情况:

代码语言:javascript
复制
B1                ,-o--o--o
                 /
A             ,-o--o
             /      \         
B2          /        '-o--o
           /               \
master  --o--o--o-----------o--

其中A是master的分支,B1和B2是A的分支。

我不认为有任何东西可以被描述为以这样的抽象术语描述的问题的最佳实践,这在很大程度上取决于所有涉及的分支的用途。

如果分支A代表一个特性的工作,打算有其他的提交,并在某个时候被合并回主节点,那么我会质疑为什么B2被合并到主节点而不是回到A。

如果A不代表特定功能的工作,但B1和B2代表,那么我认为B1可以直接合并到master中。

如果B1是从A分支出来的这一事实是一个问题,那么它可能会首先重新基于master。

归根结底,这个问题的答案取决于您的开发过程是什么样子,以及您如何在开发过程中使用分支。

票数 2
EN

Stack Overflow用户

发布于 2018-10-27 02:16:03

(从逻辑上讲,这应该是一个注释,但我需要格式化它,但我不能在注释中这样做。另外,当然,它太长了。:-) )

SpoonMeiser's answer (正确和向上)中,我们有这样一幅图:

代码语言:javascript
复制
B1                ,-o--o--o
                 /
A             ,-o--o
             /      \         
B2          /        '-o--o
           /               \
master  --o--o--o-----------o--

我觉得有必要指出这幅图有点误导:它让人们认为最下面一行提交是可以从master到达的,下一行是可以从B2到达的提交,第三行是可以从A到达的提交,最上面一行是可以从B1到达的提交。

我使用了这个奇怪的短语,reachable from,而不是更明显的单词on。为什么我们称提交是可达的,而不是仅仅说明它们在哪个分支上?

答案是提交通常是在同一时间的多个分支上进行的。让我们给每个提交一个由一个字母组成的名称(从C开始,以避免AB),并将分支名称移动到我最喜欢的右侧位置,如下所示:

代码语言:javascript
复制
             ,-E--F--G   <-- B1
            /
         ,-D--H   <-------- A
        /      \
       /        '-I--J   <-- B2
      /               \
...--C--K--L-----------M   <-- master

Git处理这些提交的方式是从每个单独的名称指向的提交开始:对于master,这是提交M,而对于分支A,它是提交H。从这一端开始提交-比如分支B2的J -然后向后工作:J指向I,然后指向HDC,依此类推。所以分支B2包含所有这些提交。同时,分支masterM开始,它同时指向JL。因此,master包含B2当前包含的所有提交,另外还包括提交LK

对于git merge应该使用的策略取决于将来想要获得的结果。也就是说,我们现在必须为明天、下周或明年要做的事情做计划。

git checkout所做的是提取分支名称所指向的提交。例如,如果我们分支B1,我们会得到git checkout G。存储在G中的快照进入我们的索引(当我们到达该点时,我们将从该索引进行下一次提交)和我们的工作树(我们可以在其中实际查看和处理文件)。如果我们做了一个新的提交,它将获得一个新的散列ID-我们将使用M后面的下一个字母,或N,并绘制它:

代码语言:javascript
复制
             ,-E--F--G--N   <-- B1 (HEAD)
            /
         ,-D--H   <-------- A
        /      \
       /        '-I--J   <-- B2
      /               \
...--C--K--L-----------M   <-- master

请注意,git commit更新了当前分支-因为git checkoutHEAD附加到分支名称,所以Git知道这一点-所以它现在指向刚刚进行的新提交。新的提交指向commit we git checkout-ed,也就是说,在我们创建新的提交之前,它是当前的提交。

git merge所做的是找到当前提交之间的合并基础--nowN-and我们命名的提交。如果我们说git merge A,名称A翻译为commit H,所以Git在图中找到commit H,在图中找到commit N,然后在这个图中反向工作,找到最佳的公共提交--在两个分支上的最佳提交。“最佳”,大致翻译过来,意思是“最接近两端”,所以这里是commit D

merge操作- to merge的动词部分-通过执行实际上的两个git diff命令来组合关于DNH

代码语言:javascript
复制
git diff --find-renames <hash-of-D> <hash-of-N>   # what we changed
git diff --find-renames <hash-of-D> <hash-of-H>   # what they changed

Git会找出我们更改了哪些文件,以及我们对它们做了什么。然后,它会找出他们更改了哪些文件,以及他们做了什么。然后,它简单地(哈)组合了这两组变化。这些组合的更改将应用于基础中的快照,这里是D,以生成新的快照。

在成功地组合了这些更改之后--至少,只要Git认为它成功地组合了它们--Git就会继续进行合并提交,就像M一样,它有两个父级。第一个父对象是commit N,第二个父对象是commit H,也就是我们选择合并的那个。像往常一样,结果被添加到HEAD分支,因此我们得到:

代码语言:javascript
复制
             ,-E--F--G--N--O   <-- B1 (HEAD)
            /  ,----------'
         ,-D--H   <-------- A
        /      \
       /        '-I--J   <-- B2
      /               \
...--C--K--L-----------M   <-- master

如果我们现在要求Git合并B1和B2,Git会走这张图来找到最佳的“公共起点”。在没有提交O情况下,公共起点是提交D,但使用O时,公共起点是H

在所有情况下,这些“普通的”Git命令只是添加到图形中。如果是常规提交,则每个新提交都有一个父提交;如果是合并提交,则每个新提交有两个父提交。添加的内容重塑了图形,合并更改了提交未来合并将选择作为其合并基础的合并。所以我们现在做的合并是我们现在需要做的事情,但它们也是我们现在做的,使我们以后可能会做的合并更容易。

有一些Git命令可以通过强制分支名称指向图中的不同(旧)位置来删除提交,而不是向图中添加新的提交。git reset命令特别擅长这一点,但git rebase也做了这件事:首先,它将一堆提交复制到“新的和改进的”提交,然后移动分支名称以指向刚刚创建的最后一个副本。一般来说,删除的提交并不会立即消失: Git会给你一个月或更长的时间来改变你的想法,然后把它们带回来。但它们确实变得很难找到,因为Git通常查找提交的方式是从分支名称(或标记名称)开始,并查看此名称找到的一个提交,然后使用该提交在整个图中反向工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53007805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档