& 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都會改變!!!)