Git 将功能正确合并到主功能中
问题: 当涉及到几个相关的特性分支时,我总是遇到同样的问题Git 将功能正确合并到主功能中,git,svn,merge,Git,Svn,Merge,问题: 当涉及到几个相关的特性分支时,我总是遇到同样的问题 master ---A---B---C \ feature1 D---E---F \ feature2 G---H 我有这样的东西。假设这两个分支都已审核,我将把feature1合并到master。然后签出并拉入master,然后签出并将feature2重设为master。这样做,我总是一次又一次地看到同样的冲突,特别是在几个分支上 mas
master ---A---B---C
\
feature1 D---E---F
\
feature2 G---H
我有这样的东西。假设这两个分支都已审核,我将把feature1
合并到master
。然后签出并拉入master
,然后签出并将feature2
重设为master
。这样做,我总是一次又一次地看到同样的冲突,特别是在几个分支上
master ---A---B---C
\
feature1 D---E---F
\
feature2 G---H
良好的重定基调:
我在网上看到,在上面的示例中,首先我应该这样做,以确保我正确地重新定基:
将feature1
重设为master
将feature2
重设为新的feature1
提交
我将使用git-rebase-on-feature1-feature1@{1}feature2来实现这一点
混乱:
据我所知,最好像这样重新设置基址,因为当您重新设置基址时,您的分支实际上将包含全新的提交(即上面的F
和F'
),这可能会导致不必要的冲突
考虑到所有这些,正确的方法是什么:
- 将
合并到feature1
master
- 将
合并到主功能中`功能2
我想尝试并学习一种推荐的方法,在这种方法中,我可以确信我不会每次都与几个从属分支发生痛苦的冲突。注意,这个答案分为两部分。第一个是关于重新基础的机制,第二个是重新基础与合并
master ---A---B---C
\
feature1 D---E---F
\
feature2 G---H
复杂地基的力学
我将使用git rebase--On feature1 feature1@{1}feature2来实现这一点
是:这是通过将参数拆分为rebase来实现的:它不再只是feature1
,而是——到feature1 feature1@{1}
通常,我们运行git-rebase-name
,例如,git-rebase-feature1
。我们必须首先git签出功能2
。将feature2
添加到命令末尾(如上所述)只会为我们执行这一git checkout
步骤。因此,在这里调用“normal”的情况下,git-rebase
只有一个参数,通常是另一个分支名称,如feature1
但是,git-rebase
所做的是复制一些提交,要做到这一点,它需要知道两件事:
- 复制内容(提交列表),以及
- 把新副本放在哪里
feature1
,对这两个参数都起着重要作用。当它工作时,这很好,但是对于在已经重新基调的功能1上重新基调功能2
,它并不总是工作
它不起作用的原因(当它不起作用时)与您绘制的图形有关。你用一种奇怪的方式画它们,左边是分支名称。这种绘图具有误导性:它意味着每次提交都在一个分支上,这是不正确的
这又是第一张图:
master ---A---B---C
\
feature1 D---E---F
\
feature2 G---H
问:提交A
在哪个分支上?(诡计问题!)
所有的树枝上都有
master ---A---B---C
\
feature1 D---E---F
\
feature2 G---H
绘制这些图时,应该将提交放在左边,标签放在右边,标签指向一个特定的提交,因为在Git中这些东西实际上就是这样工作的。这是相同的图表,重新绘制:
--A--B--C <-- master
\
D--E--F <-- feature1
\
G--H <-- feature2
这就是git-rebase
的split-up参数的作用
通常,Git会使用以下方法查找Git rebase将要复制的提交集:
git rev-list <argument>..<current-branch>
由于回流通常是不可见的,所以我们可以完全放下图表的下半部分
重设基础与合并
据我所知,最好像这样重新设置基址,因为
最好是个很滑的学期
重基有两个问题:
- 它复制提交,然后放弃原件,取而代之的是新的副本。还有人有原件吗?如果是这样的话,你也给他们带来了困难:他们也必须放弃原件,取而代之的是新的副本
- 它复制提交。新的副本至少与原件有些不同(否则它们实际上就是原件)。确切地说,副本之间有什么不同?重要吗?您是否在过程中破坏了某些东西,即引入了bug
使用git merge
可以避免这些问题。相反,它插入了自己的问题:
- 历史现在变得错综复杂。如果有必要弄清楚到底发生了什么,那么无论是谁在探索历史,都可能不得不看不起合并的两条腿。有些人认为,这是一个积极的,而不是消极的,因为这是真实的历史,而不是一个后来,清理,人工历史
(我倾向于支持经过清理的历史,但这一论点的双方都有好处。)
- 合并本身可能会引入bug
如果您有一组非常好的测试,这将有助于解决这两个“引入bug”问题
如果它足够有用,它只会留下一个重定基础问题(假设你足够聪明,或者有一个很好的工具,来做你自己的复杂重定基础,就像这个例子):其他人有原始的吗?平衡你对这个问题的回答和你对纠结的历史是否糟糕的回答,以便决定合并还是重新基础
如果你没有很好的测试,那么…:-) 您的Rebase feature2
图表有问题,并且不会因为上面显示的图表而产生问题。没有硬性规定,但在主控
上重新设置功能2
(将功能1
合并到主控
后)不一定会导致合并冲突。请记住,feature2的大部分功能已经在master中,并且从功能点重新应用了一些新的提交
G'-H' <-- feature2
/
D'-E'-F' <-- feature1
/
--A--B--C <-- master
\
D--E--F [reflog: feature1@{1}]
\
G--H [reflog: feature2@{1}]