我们正在制作两个版本,一个是小版本,一个是主版本,每个版本都有自己的git
分支。在创建主分支之前,最初将一个功能添加到次要分支。之后该功能已从次要分支中移除(使用revert
提交),因为我们决定在主要版本中引入该功能。
所以现在我们有这样一种情况:如果我们将来自次要分支的更改合并到主分支中,它将包括恢复提交,这在主要分支中没有意义。
我考虑过的一个选项是在恢复提交后对次要分支中的提交使用cherry-pick
,但这样做的缺点是任何基于次分支的分支都不能与之合并。主要分支。 (我们必须继续使用cherry-pick
来做类似的事情。)但是,它具有更准确的历史记录,因为不会包含恢复提交。
另一个选项是将所有次要分支合并到主分支中,只是“忽略”恢复变更。通过“忽略”,我的意思是在进行合并时手动恢复还原的更改。从git的角度来看,这可以更好地保留历史,但可能意味着在合并期间会有一些纠缠。
一般来说,我们只在主分支中使用合并,并且仅在合并之前调整修复最新代码。所以我倾向于选择第二种选择,但是我想在这里找出是否是处理这种情况的正确方法,或者是否有我遗漏的东西。
编辑:这是ASCII艺术: - )
* (major)
| * (minor)
* | ...
| * revert feature on minor
* | major: unrelated commit
| * minor: unrelated commit
* |
|/
* common ancestor
|
* add feature to main branch
答案 0 :(得分:6)
我很好奇你的意思,“在主要分支中没有意义。”您是否担心该功能将在主要分支上恢复?或者你是否感到恼火的是,一个名为“还原功能”的提交将出现在主要分支的历史中,而事实上该功能在那里?
如果没有更多细节,很难说合并的结果会是什么,但这里有一些可能性:
如果您的历史记录如下:
* (major)
| * (minor)
* |
| * revert feature on minor
* | cherry-pick feature onto major
| * add feature to minor
* |
|/
* common ancestor
|
然后,您可以简单地将minor
合并到major
中,而不会出现任何问题。
为什么呢?可以这样想:当您将minor
合并到major
时,您实际上是在共同祖先(git merge-base major minor
)和minor
之间进行差异,将其作为补丁应用到major
,然后创建恰好同时拥有major
和minor
作为父级的提交。
共同祖先和minor
之间的差异不包含任何添加然后恢复的功能的提示,因为两个提交相互抵消。因此,major
中引入的唯一更改是由minor
上的其他提交引起的更改。
如果您的历史记录如下:
* (major)
| * (minor)
* |
| * revert feature on minor
* | merge minor into major
|\|
* | cherry-pick feature onto major
| * add feature to minor
* |
|/
*
|
然后你有问题。在这种情况下,major
和minor
之间的共同祖先是标记为“add feature to minor
”的提交。如果你看一下这个共同祖先和minor
之间的差异,差异将包括特征的恢复。将minor
合并到major
后,此差异将应用于major
,还原major
上的功能。
在这种情况下,有几种简单的方法可以避免在major
上丢失该功能:
将minor
合并到major
,然后还原还原。结果图如下所示:
* revert the revert (major)
|
* merge minor into major
|\
* |
| * (minor)
* |
| * revert feature on minor
* | merge minor into major
|\|
* | cherry-pick feature onto major
| * add feature to minor
* |
|/
*
|
从minor
创建新分支。我们称之为minor-for-merge
。在此分支上,还原还原。然后将分支合并到major
并删除分支。结果图如下所示:
* merge minor-for-merge into major (major)
|\
| * revert the revert
* \
| * (minor)
* |
| * revert feature on minor
* | merge minor into major
|\_ |
* \| cherry-pick feature onto major
| * add feature to minor
* _/
|/
*
|
无论哪种方式都有效。后者有点尴尬 - 恢复恢复的提交在无人区域中有点悬空 - 但它可以帮助您在合并到major
时避免大量合并冲突。
无论哪种方式,minor
之外的任何分支都可以合并到major
,而不会还原该功能。如果在恢复之前建立了minor
之外的分支,则恢复将不会在合并的历史记录中。如果minor
之后的分支是在恢复之后(或者如果{{ 1}}在revert之后被合并到分支中,然后revert仍然不会在合并的历史中,因为该提交已经在minor
的祖先中。
答案 1 :(得分:2)
我认为你可以合并次要分支和'还原恢复',我的意思是
git merge <minor branch>
git revert <revert commit>
同时检查一下这个“How to Revert Faulty Merge”,这与您的问题无关,但您可以对“恢复还原”的效果有所了解。