git rebase 和 git merger

& 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

    1. 首先找到masterexperiment中最新的commit的最近公共祖先,在這裏就是c4c3的最近公共祖先c2
    2. experiment分支上在c2之後的全部commit合併成一個commit,並與master合併
    3. 若有合併衝突(兩個分支修改了同一個文件),首先人工去除重複。
    4. master上產生合併後的新commit

 

 & git rebaseblog

 

  rebase所作的事情也是合併兩個分支,可是它的方式略有不一樣。基於上例描述,rebase的工做流程是rem

    1. 首先找到masterexperiment中最新的commit的最近公共祖先,在這裏就是c4c3的最近公共祖先c2
    2. 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都會改變!!!)

相關文章
相關標籤/搜索