git merge

将当前分支合并到指定分支。


$ git merge develop

将当前分支与develop分支合并,产生的新的commit对象有两个父节点。

如果“指定分支”本身是当前分支的一个直接子节点,则会产生fast-forward合并,即合并不会产生新的节点,只是让当前分支指向“指定分支”的最新commit。

Git合并所采用的方法是Three-way merge,及合并的时候除了要合并的兩个节点,还加上它们共同的父节点。这样可以大大減少人为处理 冲突conflict 的情況。如果采用two-way merge,则只用兩个节点进行合并(svn默认就是这种合并方法。)

两路合并 two-way merge

Two-way merge解决的问题是:如何把两个文件进行合并。

举个例子,假设你和另外一个人同时修改了一个文件,这时merging算法看到了这两个文件,如下图:

merging算法发现两个文件大部分都一样,只有30行不一样,

在Yours的版本里内容是:Print("hello") 在Mine的版本里内容是:Print("bye") 但是merging算法怎么知道是你修改了30行还是另外一个人修改了?可能会有以下几种情况:

  1. Mine版本没有修改,Yours版本修改了内容(从Print("bye") 修改 Print("hello"))

  2. Yours版本没有修改,Mine版本修改了内容(从Print("hello") 修改 Print("bye"))

  3. Yours和Mine都修改了内容,(Yours从???修改成Print("hello");Mine从???修改成Print("bye")

  4. Yours和Mine都增加了一行 对于一个merge算法来说,该怎么处理上述4中情况呢?

  5. Mine版本没有修改,Yours版本修改了内容 => 应该选Yours版本

  6. Yours版本没有修改,Mine版本修改了内容 => 应该选Mine版本

  7. Yours和Mine都修改了内容 => 需要手动解决冲突

  8. Yours和Mine都增加了一行 => 需要手动解决冲突 由于缺乏必要的信息,Two-way merge根本无法帮助我们解决冲突,TA只能帮助我们发现冲突,需要手动解决冲突。

如果让merging算法知道更多一些信息,merging算法是否可以帮助我们自动解决一些简单的冲突呢?下面来看一下Three-way merge算法。

三路合并 Thee-way merge

Three-way merge是在Two-way merge的基础上又增加了一个信息,即两个需要合并的文件修改前的版本。如下图所示,merge算法现在知道三个信息:

Mine:需要合并的一个文件 Yours:另一个需要合并的文件 Base:两个文件修改前的版本

这时merging算法发现:

  1. 修改前的Base版本里的内容是:Print("bye")
  2. 在Yours的版本里内容是:Print("hello")
  3. 在Mine的版本里内容是:Print("bye")

说明Yours对这一行做了修改,而Mine对这行没有做修改,因此对Yours和Mine进行merge后的结果应该采用Yours的修改,于是就变成Print("hello")。

这就是Three-way merge的大致原理。

上一篇:git ls-files
下一篇:git pull
最近更新的
...