为什么 Git merge 在 master 分支上创建多个提交?
Why is Git merge creating multiple commits on master branch?
我正在使用两个分支,master
和 newFeature
。在构建 "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
选项,您只能对每个分支执行此操作 一次 因为通过压缩,您将丢失有关不同之处的信息在两个分支之间。
我正在使用两个分支,master
和 newFeature
。在构建 "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
选项,您只能对每个分支执行此操作 一次 因为通过压缩,您将丢失有关不同之处的信息在两个分支之间。