& git mergegit
在上图中,每个绿框均表明一个commit。除了c1,每个commit都有一条有向边指向它在当前branch当中的上一个commit。安全
图中的项目,在c2以后就开了另一个branch,名为experiment
。在此以后,master
下的修改被放到c4 commit中,experiment
下的修改被放到c3 commit中。spa
` 若是咱们使用merge
合并两个分支3d
1 $ git checkout master 2 $ git merge experiment
咱们看到,merge
所作的事情其实是:code
master
和experiment
中最新的commit的最近公共祖先,在这里就是c4
和c3
的最近公共祖先c2
。experiment
分支上在c2
之后的全部commit合并成一个commit,并与master
合并
& git rebaseblog
rebase
所作的事情也是合并两个分支,可是它的方式略有不一样。基于上例描述,rebase
的工做流程是rem
master
和experiment
中最新的commit的最近公共祖先,在这里就是c4
和c3
的最近公共祖先c2
。experiment
分支上在c2
之后的全部commit*所有移动到*master
分支的最新commit以后,在这里就是把c3
移动到c4
之后。
因为git的每个commit都只存储相对上一个commit的变化(或者说是差值,delta)。咱们经过移动c3到master
,表明着在master
上进行c3相应的修改。为了达成这一点,只需在experiment
分支上rebase master
工作流
1 $ git checkout experiment 2 $ git rebase master
须要注意的是,rebase
并非直接将c3移动到master上,而是建立一个副本。咱们能够经过实际操做发现这一点。在rebase
先后,c3的hash code是不同的。hash
rebase
前的commit log是it
* 1b4c6d6 (master) <- c4 | * 66c417b (experiment) <- c3 |/ * 972628d
rebase
后的commit log是
* d9eeb1a - (experiment) <- c3' * 1b4c6d6 - (master) <- c4 * 972628d
能够发现c3的hash code从66c417b
变到了d9eeb1a
。
在这以后,咱们只须要在master
上进行一次前向合并(fast-forward merge)
$ git checkout master $ git merge experiment
rebase
以后的commit log呈线性,更加清晰。此时若是experiment分支再也不被须要,咱们能够删除它。
$ git branch -d experiment
& git rebase 使用
永远不要rebase一个已经分享的分支(到非remote分支,好比rebase到master,develop,release分支上),也就是说永远不要rebase一个已经在中央库中存在的分支.只能rebase你本身使用的私有分支.
在执行git rebase以前,老是多问问你本身:“有没有其余人也须要这个分支来工做?”,若是答案是yes,那么你就须要思考必须使用一种非破坏性的方式来完成rebase同样的工做(就是须要合入别人的
工做成果),好比使用git revert命令。不然,若是这个branch没有别人来使用,那么很好,你能够很是安全地为所欲为地re-write history(注意rebase每每会重写历史,全部已经存在的commits虽然内容没
有改变,可是commit自己的hash都会改变!!!)