为什么 Git merge 在 master 分支上创建多个提交?

Why is Git merge creating multiple commits on master branch?

我正在使用两个分支,masternewFeature。在构建 "new feature" 时,我向 newFeature 分支添加了多个提交。我对 git merge 的理解是,一旦分支被合并,它将在 master 上创建一个 single 提交,但是当合并时,master 现在有newFeature 上的完整提交历史记录。例如-

master (pre-merge):

    1=>2=>3

newVersion:

    1=>2=>3=>4=>5=>6

master (actual results of merge):

    1=>2=>3=>4=>5=>6

master (expected results of merge):

    1=>2=>3=>6

有什么方法可以在合并期间从 newVersion 中删除中间提交,为什么合并没有按预期进行?

这里要注意的关键是,newVersion 的整个工作过程中,master 没有任何变化。在这些情况下,Git 默认为 "fast-forward" 合并,这基本上可以被认为是从 newVersion 获取所有新提交并将它们附加到 [=14] 上的最新提交=](不分隔在 newVersion 上完成的提交历史记录)。这可以用 --no-ff 标志覆盖,例如:

git merge newVersion --no-ff

结果:

master (pre-merge):

    1=>2=>3

newVersion:

    1=>2=>3=>4=>5=>6

master (actual results of merge):

    1=>2=>3=========>7
            4=>5=>6

请注意,提交 7 代表 合并,并不会替换 提交历史。

参考:https://sandofsky.com/images/fast_forward.pdf

或者,如果您希望将 newVersion 的整个提交历史合并为 master 上的单个提交(如果它们在 "new version") 你可以 运行 与 --squash 标志合并。例如:

git merge --squash newVersion

结果:

master (pre-merge):

    1=>2=>3

newVersion:

    1=>2=>3=>4=>5=>6

master (actual results of merge):

    1=>2=>3=>7

请注意,7 合并了在提交 4 - 6 中完成的提交历史

不可能有一个看起来像你想要的最终历史。 git 中的每个提交都与其父项相关联。每个提交都包含对其父项的引用,因此 6 明确引用 5.

如果您确实希望 1=>2=>3 之上添加 5 和 6 之间的变化,那么您可以使用 git cherry-pick newFeature。这将创建一个 new 提交,其中仅包含 5 和 6 之间的更改,但应用在 3 之上。

如果您想要 4、5 和 6 的所有更改但您只想要一次提交,那么您可以使用 --squash 标志到 git merge。这将创建一个 new 提交,其中包含来自 4、5 和 6 的所有更改。但是,您的历史记录不会是 1=>2=>3=>6,而是 1=>2=>3=>7,其中7 是这个新提交。

请注意,如果您选择 --squash 选项,您只能对每个分支执行此操作 一次 因为通过压缩,您将丢失有关不同之处的信息在两个分支之间。