3

我们正在开发两个版本,一个次要版本和一个主要版本,每个版本都有自己的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
4

2 回答 2

6

我很好奇您所说的“在主要分支中没有意义”是什么意思。您是否担心该功能将在主要分支上恢复?或者您只是对标题为“恢复功能”之类的提交感到恼火,而实际上该功能存在于主要分支的历史记录中?

如果没有更多细节,很难说合并的结果是什么,但这里有一些可能性:

如果您的历史记录如下所示:

*   (major)
| * (minor)
* |
| * revert feature on minor
* | cherry-pick feature onto major
| * add feature to minor
* |
|/
*   common ancestor
|

然后你可以简单地合并minormajor没有任何问题。

为什么?可以这样想:当您合并minormajor时,您实际上是在获取共同祖先 ( 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
* |
|/
*
|

那你就有问题了。major在这种情况下,和之间的共同祖先minor是标记为“ add feature to minor”的提交。如果您查看这个共同祖先 和 之间minor的差异,差异将包括该功能的恢复。当您合并minormajor时,此差异将应用于major,恢复该功能major

在这种情况下,有几种简单的方法可以避免丢失功能major

  • 合并minormajor中,然后还原还原。生成的图表如下所示:

    *   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是在还原之后进行的(或者如果在还原minor之后合并到分支中),则revert 仍然不会出现在被合并的历史记录中,因为该提交已经在major的祖先中。

于 2013-07-04T06:01:03.853 回答
2

我认为您可以合并次要分支并“还原还原”,我的意思是

git merge <minor branch>
git revert <revert commit>

还要检查这个“如何还原错误合并”,这与您的问题无关,但您可以对“还原还原”的效果有所了解。

于 2013-07-04T06:00:44.230 回答