从当前分支合并到另一个分支

To merge from the current branch into the other branch

git merge 从另一个分支 合并到当前分支。

是否可以将从当前分支合并到另一个分支,并留在当前分支?

下面当然可以,但是一共三个步骤

(on brancha)
git checkout master
git merge brancha
git checkout brancha

简短回答:不,您必须使用多步法。

稍微复杂一点的回答:是的,这是可能的,但它比多步骤方法工作更多。诀窍是:合并做两件不同的事情;这两个之一是对称的;1 这两个之一不是。

对称部分是 "coming up with a merge result"(就附加到提交的树而言)。为此,git 有一个四步过程:

  1. 找到 merge base。这是一些特定的提交2,它既是当前提交(HEAD)的祖先,也是命名的、要合并的提交(通常是某个分支的尖端) , 但您可以合并任何提交 ID)。
  2. 将合并基础与 HEAD 相比较。
  3. 将合并基础与要合并的提交进行比较。
  4. 合并两个差异,在没有冲突的地方使用自动结果,在两个差异冲突的地方使用有冲突的结果(导致合并停止并获得帮助)。3

完成所有这些后,git merge 通常会在当前分支(或分离的 HEAD 上)创建一个新的 "merge commit",当然除非你告诉它不要( git merge --no-commit) 或因冲突而停止。

这个新提交是非对称部分。鉴于上述情况(并忽略潜在的 rerere 情况,因为这些情况可能取决于 diff 对的顺序),如果您阻止新提交,您将获得相同的 tree 无论您使用哪个 "direction" 进行合并。但是你会得到一个不同的 commit,因为新的合并提交有三个有趣的属性:

  • 父列表:列表相同,但顺序取决于合并的方向。合并的 first 父级始终是被合并到的提交(当前分支),其 second 父级是被合并到的提交(合并分支或提交)。
  • 提交消息:默认消息显示 "merge branch mergefrom",因此出现合并分支的名称。
  • 当前分支的自动调整:这与任何新提交相同。如果您在分支 master 上,并且您进行了新的提交,master 指向的 SHA-1 将更新,以便 master 指向新的提交。在这种情况下,这是新的合并提交。

如果我们停止写入实际的合并提交(使用--no-commit),我们将得到正确的(忽略某些rerere情况).然后我们可以使用正确的父项、树和日志消息创建一个新的提交,并使用 git write-tree 更新 other 分支,而不是我们所在的分支和 git commit-tree 在某处写入新提交,然后使用 git update-ref 更新我们所在分支以外的引用。 git commit-tree 命令按照我们控制的顺序获取父 SHA-1 ID 的列表,并使用 -m-F 来设置提交消息,并且不会推进当前分支(新提交对象的 ID 只是简单地写入标准输出),所以这都是可行的,但不是可行的方法。


1除了 "ours" 与 "theirs" 进行正常(非章鱼)合并时,以及其他相应的微妙之处,例如冲突的合并条目在索引中,以及 rerere 种可能性。

2这掩盖了递归合并在某些情况下使用的"virtual base",但即便如此,原理仍然相同。

3更准确地说,碰撞不仅仅是 "make the same change",它通过仅进行一次而不是两次更改来自动解决。或者,如果启用了 rerere,git 会检查它可以 "re" 使用的 "re" 编码 "re" 冲突解决方案,然后将重用它而不是停下来。