什么是 Git 中的三路合并或合并提交?


让我们来看一个三路合并的例子。在这个例子中,Feature 分支比Master 分支超前两个提交。

图 1

在我们将其与 Master 合并之前,假设我们在 Master 中添加了另一个提交,如下面的图所示。

图 2

由于在 Master 分支上进行了提交,我们的MasterFeature 分支现在都已分叉。

这意味着Master 分支中有一些Feature 分支中没有的更改。如果在这种情况下执行合并,Git 将无法将 master 指针移向Feature 分支。

如果 git 只是将 Master 指针移动到Feature 指针,那么在Master 分支上执行的最新提交C6 将丢失。

那么,如果分支已分叉,我们如何执行合并呢?

当我们想要合并已分叉的分支时,Git 会创建一个新的提交(合并提交),并将这两个分支的更改合并在一起,如下面的图所示。

图 3

它被称为三路合并的原因是合并提交基于三个不同的提交。

  • 我们分支的共同祖先,在本例中是提交编号C3。此提交包含我们在分叉成不同分支之前的代码。

  • Master 分支的顶端,即在 Master 分支上执行的最后一个提交 - C6

  • Feature 分支的顶端,即在 Feature 分支上执行的最后一个提交 - C5

为了合并来自这两个分支的更改,Git 会查看三个不同的快照 - 之前的快照和之后的快照。基于这些快照,Git 通过创建名为合并提交的新提交来合并更改。

示例

$ git init
$ echo one>1.txt
$ git add .
$ git commit -m 'c1'
$ echo two>2.txt
$ git add .
$ git commit -m 'c2'
$ echo three>3.txt
$ git add .
$ git commit -m 'C3'
$ git branch feature
$ git switch feature
$ echo four>4.txt
$ git add .
$ git commit -m 'c4'
$ echo five>5.txt
$ git add .
$ git commit -m 'c5'
$ git switch master
$echo six>6.txt
$ git add .
$ git commit -m 'c6'
$ git merge feature
$ git log --oneline --all --graph

输出

hint: Waiting for your editor to close the file... unix2dos: converting file E:/git_clone/test_repo/.git/MERGE_MSG to DOS format...
dos2unix: converting file E:/git_clone/test_repo/.git/MERGE_MSG to Unix format...
Merge made by the 'recursive' strategy.
4.txt | 1 +
5.txt | 1 +
2 files changed, 2 insertions(+)
create mode 100644 4.txt
create mode 100644 5.txt

* e1ce060 (HEAD -> master) Merge branch 'feature'
|\
| * 3435c89 (feature) c5
| * 7e7761b c4
* | 5618675 c6
|/
* 6ad93bf C3
* 9031c20 c2
* 3f68f83 c1

更新于:2021年4月30日

5K+ 次浏览

启动您的职业生涯

完成课程获得认证

开始
广告