当一个人拥有另一个不想要的还原时,合并git分支

时间:2013-07-04 03:42:12

标签: git git-merge

我们正在制作两个版本,一个是小版本,一个是主版本,每个版本都有自己的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

2 个答案:

答案 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,然后创建恰好同时拥有majorminor作为父级的提交。

共同祖先和minor之间的差异不包含任何添加然后恢复的功能的提示,因为两个提交相互抵消。因此,major中引入的唯一更改是由minor上的其他提交引起的更改。

如果您的历史记录如下:

*   (major)
| * (minor)
* |
| * revert feature on minor
* | merge minor into major
|\|
* | cherry-pick feature onto major
| * add feature to minor
* |
|/
*
|

然后你有问题。在这种情况下,majorminor之间的共同祖先是标记为“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”,这与您的问题无关,但您可以对“恢复还原”的效果有所了解。