【Git】rebase 用法小結(jié)

歡迎關(guān)注微信公眾號(hào):全棧工廠

本文主要參考

rebase在git中是一個(gè)非常有魅力的命令,使用得當(dāng)會(huì)極大提高自己的工作效率;相反,如果亂用,會(huì)給團(tuán)隊(duì)中其他人帶來(lái)麻煩。它的作用簡(jiǎn)要概括為:可以對(duì)某一段線性提交歷史進(jìn)行編輯、刪除、復(fù)制、粘貼;因此,合理使用rebase命令可以使我們的提交歷史干凈、簡(jiǎn)潔!

前提:不要通過(guò)rebase對(duì)任何已經(jīng)提交到公共倉(cāng)庫(kù)中的commit進(jìn)行修改(你自己一個(gè)人玩的分支除外)

1.合并多個(gè)commit為一個(gè)完整commit

當(dāng)我們?cè)诒镜貍}(cāng)庫(kù)中提交了多次,在我們把本地提交push到公共倉(cāng)庫(kù)中之前,為了讓提交記錄更簡(jiǎn)潔明了,我們希望把如下分支B、C、D三個(gè)提交記錄合并為一個(gè)完整的提交,然后再push到公共倉(cāng)庫(kù)。

現(xiàn)在我們?cè)跍y(cè)試分支上添加了四次提交,我們的目標(biāo)是把最后三個(gè)提交合并為一個(gè)提交:


這里我們使用命令:

  git rebase -i  [startpoint]  [endpoint]

其中-i的意思是--interactive,即彈出交互式的界面讓用戶編輯完成合并操作,[startpoint] [endpoint]則指定了一個(gè)編輯區(qū)間,如果不指定[endpoint],則該區(qū)間的終點(diǎn)默認(rèn)是當(dāng)前分支HEAD所指向的commit(注:該區(qū)間指定的是一個(gè)前開(kāi)后閉的區(qū)間)。
在查看到了log日志后,我們運(yùn)行以下命令:

git rebase -i 36224db

或:

git rebase -i HEAD~3 

然后我們會(huì)看到如下界面:


上面未被注釋的部分列出的是我們本次rebase操作包含的所有提交,下面注釋部分是git為我們提供的命令說(shuō)明。每一個(gè)commit id 前面的pick表示指令類型,git 為我們提供了以下幾個(gè)命令:

  • pick:保留該commit(縮寫(xiě):p)
  • reword:保留該commit,但我需要修改該commit的注釋(縮寫(xiě):r)
  • edit:保留該commit, 但我要停下來(lái)修改該提交(不僅僅修改注釋)(縮寫(xiě):e)
  • squash:將該commit和前一個(gè)commit合并(縮寫(xiě):s)
  • fixup:將該commit和前一個(gè)commit合并,但我不要保留該提交的注釋信息(縮寫(xiě):f)
  • exec:執(zhí)行shell命令(縮寫(xiě):x)
  • drop:我要丟棄該commit(縮寫(xiě):d)

根據(jù)我們的需求,我們將commit內(nèi)容編輯如下:

然后是注釋修改界面:


編輯完保存即可完成commit的合并了:

2.將某一段commit粘貼到另一個(gè)分支上

當(dāng)我們項(xiàng)目中存在多個(gè)分支,有時(shí)候我們需要將某一個(gè)分支中的一段提交同時(shí)應(yīng)用到其他分支中,就像下圖:


我們希望將develop分支中的C~E部分復(fù)制到master分支中,這時(shí)我們就可以通過(guò)rebase命令來(lái)實(shí)現(xiàn)(如果只是復(fù)制某一兩個(gè)提交到其他分支,建議使用更簡(jiǎn)單的命令:git cherry-pick)。
在實(shí)際模擬中,我們創(chuàng)建了master和develop兩個(gè)分支:
master分支:
develop分支:
我們使用命令的形式為:

    git rebase   [startpoint]   [endpoint]  --onto  [branchName]

其中,[startpoint] [endpoint]仍然和上一個(gè)命令一樣指定了一個(gè)編輯區(qū)間(前開(kāi)后閉),--onto的意思是要將該指定的提交復(fù)制到哪個(gè)分支上。
所以,在找到C(90bc0045b)和E(5de0da9f2)的提交id后,我們運(yùn)行以下命令:

    git  rebase   90bc0045b^   5de0da9f2   --onto master

注:因?yàn)?code>[startpoint] [endpoint]指定的是一個(gè)前開(kāi)后閉的區(qū)間,為了讓這個(gè)區(qū)間包含C提交,我們將區(qū)間起始點(diǎn)向后退了一步。
運(yùn)行完成后查看當(dāng)前分支的日志:

可以看到,C~E部分的提交內(nèi)容已經(jīng)復(fù)制到了G的后面了,大功告成?NO!我們看一下當(dāng)前分支的狀態(tài):
當(dāng)前HEAD處于游離狀態(tài),實(shí)際上,此時(shí)所有分支的狀態(tài)應(yīng)該是這樣:

所以,雖然此時(shí)HEAD所指向的內(nèi)容正是我們所需要的,但是master分支是沒(méi)有任何變化的,git只是將C~E部分的提交內(nèi)容復(fù)制一份粘貼到了master所指向的提交后面,我們需要做的就是將master所指向的提交id設(shè)置為當(dāng)前HEAD所指向的提交id就可以了,即:

      git checkout master
      git reset --hard  0c72e64

此時(shí)我們才大功告成!

注:文中如有任何錯(cuò)誤,請(qǐng)各位批評(píng)指正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容