菏泽市万贯网络科技有限公司
首页 | 联系方式 | 加入收藏 | 设为首页 | 手机站

产品目录

联系方式

联系人:业务部
电话: 00145-669996
邮箱:service@sdlcjrgg.com

当前位置:首页 >> 产品展示 >> 默认分类 >> 正文

(译)第二部分:什么是merge?

详细信息:

内容提要

  • 第一部分:commit hash是什么?
  • 第二部分:merge是什么?
  • 第三部分:rebase是什么?

在第一部分我们创建了一个小的demo仓库,它拥有着一个feature1分支,而且这个分支已经准备好要merge到master分支中了。

此时,我们可以选择merge或者rebase feature1分支到master分支。关于rebase将会在第三部分进行介绍。现在我们来看一下,采用merge的方式到底发生了什么。把分支合并到一起是非常直接的。首先需要将切换到要合并进去的分支,在这里,因为我们要将feature1合并到master分支,所以需要切换到master分支。

我切换到master分支,然后将feature1分支合并进去。回过头来再看一下这之中发生了什么,为什么Source Tree生成的图形是这个样子的。

还记得第一部分中Commit 3Commit 4引用着同一个先前commit吗?Commit 2是这两个commit共同的祖先,因为Commit 3是在另一个分支上创建的,而Commit 4是在master分支上创建的,所以它完全不知道Commit 3的存在。在feature1上我们添加了更多的commit。Commit 5直接引用了Commit 3,因为Commit 4只在master分支上有效,Commit 6直接引用了Commit 5

当我们将feature1合并到master中,它并不是通过某种方式神奇地把这些commit都移到master分支上。实际上,它创建了一个包含了feature1分支上所有的变更的全新commit。这个commit叫Merge branch 'feature1',就像这样:

如果你注意到上图中的commit差异,就会看到我添加到index.txt中二了吧唧的这几行。你应该会注意到这几行是通过各个commit分开地添加进去的。然而,现在你看到的是所有的这些改变都在单一的一个差异中。

Git所做的只是把feature1中所有的commit的所有差异汇聚到一个单一的commit中。这个新的commit干了一些我们之前没有讨论过的事。从上图可以看到它拥有2个祖先,也就拥有着从Commit 4Commit 6过来的两条线。为什么呢?commit可以保存多个先前commit的索引。我现在才来讲这个话题是因为我不想太早地引起混淆。

当一个commit被创建的时候,它所引用的之前commit数量可以是一个,多个,甚至没有。通常只有仓库中第一个commit才会没有先前commit,而merge commit一般都拥有超过一个的先前commit。

如果你还记得第一部分的话,分支,其实实际上只是一个指向一个指定commit的指针而已。

你可能会注意到feature1仍然指向了Commit 6,而master分支指向了新的merge commit,很简单,因为我们是将feature1 合并到master。如果我们将分支切换到feature1,然后再把master合并进来,那么Git所做的就是一个fast-forward marge(快进合并),这会把feature1的指针指向最新的commit。

如果我们完全删除了feature1分支,你可能会以为粉色的线消失,但是你错了。

记住,Source Tree和其他的Git可视工具是通过遍历你的commit,用索引的commit hash连接各个commit来生成图形的。分支只是一个指向指定commit的指针。当你从一个远程仓库拉取更新(pull)时,Git所做的是:

  • 1.下载所有你本地机器上没有的commit
  • 2.合并丢失的commit到你的本地仓库,或是通过一个merge commit,或是通过一个fast-forward merge,前提是你在最后一次拉取更新后没有做任何的修改。
  • 3.把你的本地分支指向最新的commit。

如果你曾经混淆过masterorigin/master指针,那现在你应该知道它们是是啥了。origin/master告诉你你的origin远程master分支指向哪。如果我给这个demo仓库添加了一个远程仓库叫origin,然后在本地仓库上做了一些commit,Git的历史可能会像这样:

你会看到master分支指向了最新的commit,而origin/master指向了前一个merge commit。Source Tree甚至提示我们说有一个commit可以推送(push)到远程仓库。如果我们推送上去,Git将会上传丢失的commit,然后更新你的远程分支指针,此时origin/master已经和你的本地master分支指向了相同的commit。

希望你现在对Git的合并功能有了更好的理解。跳到第三部分让我们深究下rebase,看看它和merge有什么区别吧唧。

英文地址:http://codetunnel.com/merge-vs-rebase-part-2-what-is-a-merge/