Git笔记 (8)

另外,分支的创建是非常快的,只需创建一个新的指针即可,切换分支也非常地块,这可以让我们很灵活而不受干扰地工作。

6.5 合并分支

分支整合可以通过两种命令:一种是基于git merge命令,另一种是基于git rebase命令。

6.5.1 git merge——三方合并

git merge是一种保存分支结构的合并,并且是三方合并,通过实例来看吧。

$ git merge testing #会跳出commit记录文件,默认退出即可 Merge made by the 'recursive' strategy. README | 1 + 1 file changed, 1 insertion(+) $ git log --oneline --decorate --graph --all -6 * f23a940 (HEAD -> master) Merge branch 'testing' |\ | * 8b6bbb7 (testing) add print(3) into README * | ce53a90 add MIT LICENSE |/ * ebc9b45 add print(2) into README * 326dd0b add print(1) into README * b861d60 branch note begin

上面可以很直观地看出提交历史,用图形表示如下:

image_1clfpn074131g1o1tt9l63nbb188.png-16.1kB


既然叫三方合并,是那三方呢?见下图

image_1clfq8dr31dgt12fjc7hmfgkkm8l.png-16.2kB


上图中浅蓝色方块就是三方,分别是当前分支,要合并的分支,以及这两者的共同祖先(这个由git自己决定),merge合并会根据当前分支与祖先的差异和要合并的分支与祖先的差异进行共同合并。

6.5.2 git rebase——变基

合并还有一种方法:那就是提取某一分支(8b6bbb7)中引入的补丁和修改,然后在另一分支(ce53a90)的基础上应用一次。在Git中,这种操作就叫做变基。可以使用 rebase命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。

$ git reset --hard ce53a90 #首先通过reset回溯到合并前的状态 HEAD is now at ce53a90 add MIT LICENSE $ git log --oneline --decorate --graph --all -5 * ce53a90 (HEAD -> master) add MIT LICENSE | * 8b6bbb7 (testing) add print(3) into README |/ * ebc9b45 add print(2) into README * 326dd0b add print(1) into README * b861d60 branch note begin $ git checkout testing #切换到要进行合并的分支 $ git rebase master #使用rebase命令将testing合并到master First, rewinding head to replay your work on top of it... Applying: add print(3) into README $ git log --oneline --decorate --graph --all -5 * 972909a (HEAD -> testing) add print(3) into README * ce53a90 (master) add MIT LICENSE * ebc9b45 add print(2) into README * 326dd0b add print(1) into README * b861d60 branch note begin

通过git log命令,整个历史可以看到没有想merge那样的分岔路,而是一条笔直的提交。rebase的原理是首先找到两个分支(即当前分支 testing、变基操作的目标基底分支master)的最近共同祖先,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底master,最后以此将之前另存为临时文件的修改依序应用。之前分支出去的提交就没有了延续,不会出现在提交历史中了。可以用新的图来表示这个过程。

image_1clgaa77rlh01tst1cckk151fm195.png-12.8kB

无论是通过三方merge合并,还是通过rebase变基,最后的结果是一样的,唯一不同的是提交历史的区别,merge还会保存分支的历史,而rebase则不会,它的提交历史是没有分叉的直线,相对整洁。

6.5.2.1 多重变基

现在用commit id来简单表示校验和,你在主分支中的C2上创建了一个特性分支server,为服务端添加了一些功能,提交了C3和C4。然后从C3上创建了特性分支client,为客户端添加了一些功能,提交了C8和C9。最后,你回到server分支,又提交了C10。(ps:这里没有进行代码实践,有兴趣的朋友可以自己试试)

image_1clgoipfepthue1crleu516mdek.png-23.3kB


现在你希望将client中的修改合并到主分支并发布,但暂时并不想合并 server 中的修改,因为它们还需要经过更全面的测试。这时,你就可以使用git rebase命令的--onto选项,选中在client分支里但不在server分支里的修改(即C8和C9),将它们在master分支上重放:

$ git rebase --onto master server client

以上命令的意思是:“取出client分支,找出处于client分支和server分支的共同祖先之后的修改,然后把它们在 master分支上重放一遍”。效果如下:

image_1clgorr5q5no1it51qt415nb18hsf1.png-19.7kB


然后进行快速合并,

$ git checkout master $ git merge client

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppgpw.html