目錄
rebase是什麼
rebase是一個git指令,通常用於合併分支
、重定分支的base
、修改commit
rebase和merge有差嗎
rebase | merge | |
---|---|---|
難易度 | 較難 | 易 |
合併時產生commit | × | ○ (ex: Merge pull request ... from ...、Merge branch ... into ...) |
合併後分支的樣子 | 一條直直的 | 兩條分支到上面的時候變一條 |
呈現時間先後 | 混亂 | 清楚 |
git graph - 合併的樣子
一開始git graph長這樣
merge
rebase
rebase怎麼合併分支
你的分支應該從main的HEAD分出去
(在gitgraph上看到會是一條直直的
,沒有和main岔開)
但是當有多個分支的時候,若是某個分支
PR已過,且先被合併到main時
,那你的分支就不再是從main的HEAD分出去了(在gitgraph上看到會是分岔的
)
這時會需要使用rebase重新定你的分支的base,步驟如下
- 先把遠端的所有分支東西都拉下來
git fetch —-all git pull
checkout到rebase的分支
git checkout 分支名
重新定義你的分支的base為main目前的HEAD
之後會看到一些原本在你們分支上不存在,或者被修改過的檔案
git rebase main
- 如果有衝突先解,然後再丟到暫存區(如果沒衝突不會有這個步驟)
git add .
- 繼續rebase(如果沒衝突不會有這個步驟)
git rebase —-continue
- 確認你的分支原有的commit都還在後,強制推到你的分支
如果有少可以cherry-pickgit push --force
rebase怎麼修改commit
調換commit的順序
只有特殊情況會這麼做
- 終端機跳到vim模式
git rebase -i commit編號~
- 按i進入vim的編輯模式
- 把commit整行移到想要的位置
- esc跳出編輯模式,shift+:進入指令模式,wq儲存並離開
- 推上去
git push --force
多個commit變一個
一開始git graph長這樣,我們要把tempura、ninja、and、samurai合成一個
- 終端機跳到vim模式
git rebase -i commit編號~
- 按i進入vim的編輯模式
- 把想要壓到別的commit裡的commit前面的pick改成s(squash)
- esc跳出編輯模式,shift+:進入指令模式,wq儲存並離開
- 終端機的vim會跳到詢問是否編輯commit message的畫面
如果要用其中一個可以把不要的部分刪掉(dd可以直接刪除鼠標所在的那行),如果要修改則按i
- shift+:進入指令模式,wq儲存並離開
- 推上去
git push --force
一個commit變多個
一個commit裡包含的東西太多,也就是一個commit的顆粒度太大時,如果團隊有code review的機制,這會造成review的困難,所以才要拆分commit
一開始git graph長這樣,我們要把tempura ninja and samurai拆成兩兩一組
- 查看要拆的commit的編號
git log
- 終端機跳到vim模式
git rebase -i commit編號~
- 按i進入vim的編輯模式
- 把想要拆開的commit前面的pick改成e(edit)
- esc跳出編輯模式,shift+:進入指令模式,wq儲存並離開
- 把舊的部分砍下來
之所以要把舊的部分砍下來是因為這樣commit才會回到暫存區,回到暫存區後才能重新編輯或者commit
git reset HEAD~
重新commit
繼續rebase
git rebase --continue
- 推上去
git push --force
舊的commit卡在新的PR上怎麼辦
這是因為上次PR用rebase合併分支後沒有把本地分支刪掉,或者重定base
下面只寫要怎麼刪掉重來,重定base可以看前面
- 刪掉分支重開
- 先把本地分支a改名b
git branch -m 舊分支名 新分支名
- 刪除本地的分支a
不用刪除遠端分支是因為合併後它已經和main沒有掛鉤
雖然遠端分支不會出現在git graph上,但在被git回收掉前還是存在的git branch -d 分支名
- 切到要當base的分支(假設是main)
git checkout main
- git branch A / 建立新分支A
git branch A
- 將分支A發到遠端
git push --set-upstream origin 分支名
- 確認目前本地跟遠端的分支目前有什麼
git branch --all
把本地分支b的commit複製到新開的遠端分支A
git cherry-pick commit編號
想改commit message的話可以加上-no-commit flag就不會把原本的貼過來
git cherry-pick —no-commit commit編號
cherry-pick完後把本地的分支b刪掉
rebase失敗搞得一團亂怎麼辦
rebase對於不熟的人相對來說是個比較容易踩雷的指令(我就踩過幾次),如果真的把git graph搞得一團亂弄不回去,還是能放大絕reset
git reset commit編號
reset就是整個砍掉重來
,它會把你的commit都砍下來丟回暫存區(預設是mixed的情況來說),這樣就可以把做壞的部分重做了
手殘開到reset hard模式怎麼辦
reset hard模式會導致改過的地方都丟失,不過仍可以使用reflog救回來
查看reflog的SHA-1編號
reflog只會在你的本地端存在
,所以只要換了電腦就沒了git reflog
- 找到你想回去的commit點的SHA-1編號
- 復原
git reset commit編號 --hard