如今假設咱們有一個主分支 master 及一個開發分支 deve,倉庫歷史就像這樣:git
初始倉庫歷史fetch
如今若是在 master 分支上 git merge deve
:Git 會自動根據兩個分支的共同祖先即 e381a81
這個 commit 和兩個分支的最新提交即 8ab7cff
和 696398a
進行一個三方合併,而後將合併中修改的內容生成一個新的 commit,即下圖的 78941cb
spa
merge 合併圖code
rebase 是什麼狀況呢?仍是一個初始的倉庫歷史圖:ip
rebase初始倉庫歷史開發
若是是在 master 分支上 git rebase deve
:Git 會從兩個分支的共同祖先 3311ba0
開始提取 master 分支(當前所在分支)上的修改,即 85841be
、a016f64
與 e53ec51
,再將 master 分支指向 deve 的最新提交(目標分支)即 35b6708
處,而後將剛剛提取的修改依次應用到這個最新提交後面。操做會捨棄 master 分支上提取的 commit,同時不會像 merge 同樣生成一個合併修改內容的 commit,至關於把 master 分支(當前所在分支)上的修改在 deve 分支(目標分支)上原樣複製了一遍,操做完成後的版本歷史就像這樣:rem
rebase 合併圖同步
能夠看見 master 分支從 deve 分支最新提交 35b6708
開始依次提交了本身的三個 commit(因爲是提取修改後從新依次提交,故 commit 的 hash 碼與上面的85841be
、a016f64
、e53ec51
不一樣)hash
rebase 操做加上 -i
選項能夠更直觀的看見被提取的 commit 信息。
仍然在 master 分支上 rebase deve 分支,不過此次要加上 -i
選項,即 git rebase -i deve
,而後咱們能夠獲得這樣一個文本信息框it
rebase -i信息
f9a7673
與 edb2ba2
),會鏈接到目標分支的哪一個 commit (9c86a5c
)後面。能夠根據 B 區域中的命令說明修改 pick
爲其餘命令,對該次提取出來的 commit 作額外的操做:wq
保存退出後,就會按照剛剛在 A 區域內設定的命令處理 commit 並 rebase。git rebase --continue
繼續,或者 --skip
跳過(注意此操做中當前分支的修改會直接覆蓋目標分支的衝突部分),亦或者 --abort
直接中止該次 rebase 操做merge --no-ff
與 merge --ff-only
的區別上面對 merge 的講述都是基於其默認操做即 --no-ff
(git merge xxx
= git merge --no-ff xxx
)的說明,可是 merge 還有一種經常使用的選項 --ff-only
,那麼這兩種有什麼區別呢?
--no-ff
是 merge 的默認操做,三方合併並提交修改;而 --ff-only
會判斷當前分支能否根據目標分支快速合併,就像下面這樣
快速合併
此時 deve 分支就可與 master 分支快速合併。
在 deve 分支上 git merge --ff-only master
,便獲得合併完成後的版本歷史圖
快速合併完成
能夠發現 --ff-only
生成的歷史記錄和 rebase 十分類似,可是本質上 --ff-only
仍然是合併操做,但 rebase 並無作合併,僅僅是提取修改到目標分支後面。
git help <command>
查看--no-ff
默認操做,生成一個對回顧提交歷史並不友好的合併記錄,仍是採用 --ff-only
方式git fetch + git merge --no-ff
兩個操做,能夠經過加上 --rebase
命令將 fetch 後的 merge 操做改成 rebase 操做,或者僅僅 'git fetch remoteName',而後才思考採起哪一種整合策略 git merge(or rebase) origin/master
git stash
命令暫存做者:不在服務區 連接:http://www.jianshu.com/p/c17472d704a0 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。