git rebase的使用

SHUIPING_YANG發表於2018-08-15
git圖形化學習網站: https://learngitbranching.js.org/

git rebase有兩種使用場景:

1.git rebase 合併多個本地commit

我習慣於有改動就提交,這樣就導致一個問題,一個功能可能在本地提交了三四次,這時候就需要進行整合提交資訊了。如下圖所示,我需要把最後的三個提交合併成一個提交,並儲存每個提交的修改.
在這裡插入圖片描述

會用到以下這條命令:

git rebase -i HEAD~3 	#合併最後三次提交
git rebase -i  commitId		#合併到需要的commitId

在這裡插入圖片描述
這裡的意思就是,有幾個引數可以選擇:

p:pick ,用這個分支的commit,保留備註資訊
r:reword 用這個提交,但是修改備註資訊
s:squash ,用這個提交,但是是把這個提交與前一個提交合並

這裡我選用pick和squash,都可以簡寫.
在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述
到這裡就結束了,這樣就把最後面的三個提交合併成一個提交了.
這個是互動式的修改,適用於未推送到遠端,也就是未執行git push的情況。如果已經推送到遠端了,就比較麻煩,需要所有協作人員統一執行 git pull --rebase 才能達到這個效果.如果有人git pull,那人後面又提交,那就很混亂了.

恢復git reset --hard 的後面的提交

https://git-scm.com/book/zh/v1/Git-內部原理-維護及資料恢復

2.git rebase合併分支和git merge的區別

假設你現在基於遠端分支"origin",建立一個叫"mywork"的分支。

$ git checkout -b mywork origin

在這裡插入圖片描述

現在我們在這個分支做一些修改,然後生成兩個提交(commit).

$ vi file.txt
$ git commit
$ vi otherfile.txt
$ git commit

但是與此同時,有些人也在"origin"分支上做了一些修改並且做了提交了. 這就意味著"origin"和"mywork"這兩個分支各自"前進"了,它們之間"分叉"了。
在這裡插入圖片描述

在這裡,你可以用"pull"命令把"origin"分支上的修改拉下來並且和你的修改合併; 結果看起來就像一個新的"合併的提交"(merge commit):
在這裡插入圖片描述

但是,如果你想讓"mywork"分支歷史看起來像沒有經過任何合併一樣,你也許可以用 git rebase:

 git checkout mywork
 git rebase origin

這些命令會把你的"mywork"分支裡的每個提交(commit)取消掉,並且把它們臨時 儲存為補丁(patch)(這些補丁放到".git/rebase"目錄中),然後把"mywork"分支更新 到最新的"origin"分支,最後把儲存的這些補丁應用到"mywork"分支上。
在這裡插入圖片描述

當’mywork’分支更新之後,它會指向這些新建立的提交(commit),而那些老的提交會被丟棄。 如果執行垃圾收集命令
(pruning garbage collection), 這些被丟棄的提交就會刪除. (請檢視 git gc)
在這裡插入圖片描述

現在我們可以看一下用合併(merge)和用rebase所產生的歷史的區別:

在這裡插入圖片描述

在rebase的過程中,也許會出現衝突(conflict). 在這種情況,Git會停止rebase並會讓你去解決 衝突;在解決完衝突後,用"git-add"命令去更新這些內容的索引(index), 然後,你無需執行 git-commit,只要執行:

git rebase --continue

這樣git會繼續應用(apply)餘下的補丁。在任何時候,你可以用 --abort 引數來終止rebase的行動,並且"mywork" 分支會回到rebase開始前的狀態。

git rebase --abort

git rebase 是在當前分支下操作,操作的結果是把當前分支頂到要合併的分支的最前面.這就導致了一個現象,提交不是按照時間往後排的,而是按照rebase的順序來進行.
當我們使用Git log來參看commit時,其commit的順序也有所不同。

假設C3提交於9:00AM,C5提交於10:00AM,C4提交於11:00AM,C6提交於12:00AM,

對於使用git merge來合併所看到的commit的順序(從新到舊)是:C7 ,C6,C4,C5,C3,C2,C1 (時間順序)

對於使用git rebase來合併所看到的commit的順序(從新到舊)是:C7 ,C6‘,C5’,C4,C3,C2,C1 (rebase相當於整個嫁接到前面)

因為C6’提交只是C6提交的克隆,C5’提交只是C5提交的克隆,

從使用者的角度看使用git rebase來合併後所看到的commit的順序(從新到舊)是:C7 ,C6,C5,C4,C3,C2,C1

相關文章