Git rebase 驚魂記

URL Link //n.sfs.tw/16168

2023-04-23 01:52:41 By 張○○

<<這篇算是半技術半札記。>>

git 是很多工程師的幫手…也是夢靨

事發原是因是這樣的,我在遠端有git server,沒事的時候會把目前的進度push上去,這一切都很美好。

但是因為我的檔案非常的多,目前已達8個g的大小,隨著push次數的增加,我發現server所耗費的同間竟達到43g,足足是本地端11g的4倍多。

這樣下去我的git SERVER就要爆了…那可不行。

所以我想了一個方法,就是把多餘的commit刪掉:我認為永遠不可能reset回去的commit。

我以為我把這些多餘的commits刪掉後,占碟空間就會大量的減小。

所以我就進行rebase的工作:

# git log --oneline
c56d23b BEFORE REBASE OK
b610d11 BEFORE REBASE
ad77bb5 圖片移動redo
9a792a7 移動content圖片到子目錄
2751427 update1120316+IP6位址
e9546d3 放到gitlab init
d7328ce 新增line登入
0c0863d 加上google authenticate
 ...
ef5bb63 add 寬1440
de999ce add 大字版本
b0f5034 up0327
05eeebd uo0303
24ce86a up0131
5fbca73 new init  <== REBASE 到這裡

於是我下指令

# git rebase -i 5fbca73

出現編輯器,裡面的順序是由舊到新,我把下面畫線的都刪掉後按:wq 存檔。

pick 24ce86a up0131
pick 05eeebd uo0303
pick b0f5034 up0327
pick de999ce add 大字版本
pick ef5bb63 add 寬1440
  ...
pick 0c0863d 加上google authenticate
pick d7328ce 新增line登入
pick e9546d3 放到gitlab init
pick 2751427 update1120316+IP6位址
pick 9a792a7 移動content圖片到子目錄

ad77bb5 圖片移動redo  <== 留這個commit
pick b610d11 BEFORE REBASE
pick c56d23b BEFORE REBASE OK <== 留最後一個commit

# Rebase 5fbca73..c56d23b onto 5fbca73
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#

換句話說,我只留2個commits,其它都不要,我以為這樣就能保留最後的狀態。

因為目錄檔案很多,存檔後等他執行,足足跑了半小時,過程中我發現情況不對,因為網頁可以重新整理,可以看到過程中的變化,原本有更新的內容不見了…

整個跑完後傻眼。

原來我沒有pick的commit,他所進行的異動也就不見了…

啊慘…

於是我想了兩個方案,一是從遠端把資料蓋回來,當然這個難度很高,很容易出意外;一個找有沒有回復的方法?[2]

下了reflog的指令

# git reflog
a9f982e HEAD@{0}: rebase -i (finish): returning to refs/heads/master
a9f982e HEAD@{1}: rebase -i (pick): BEFORE REBASE OK
50ea89f HEAD@{2}: rebase -i (pick): 圖片移動redo
5fbca73 HEAD@{3}: checkout: moving from master to 5fbca73b7c499e1fb7a8e5bf5845aa7214dad004
c56d23b HEAD@{4}: commit: BEFORE REBASE OK <== 找到最後的commit進行恢復
b610d11 HEAD@{5}: commit: BEFORE REBASE
ad77bb5 HEAD@{6}: commit: 圖片移動redo
9a792a7 HEAD@{7}: commit: 移動content圖片到子目錄
2751427 HEAD@{8}: commit: update1120316+IP6位址
e9546d3 HEAD@{9}: commit: 放到gitlab init
0c0863d  <== 的確就是印這樣,後面沒有了。

下reset的指令恢復原本的狀態

# git reset --hard HEAD@{4}
Checking out files: 100% (51341/51341), done.
HEAD is now at c56d23b BEFORE REBASE OK

上面的reset很快,只花了幾秒。

回復原來的狀況,我想我得進行plan B,把原來的git全刪掉。

結論

1. rebase 刪掉commit是指該commit做的事也取消。

2. rebase完畢後後悔時可以用reset回復,但是重點是rebase得成功。

3. 不要完全依賴git,實體備份也很重要。

參考資料

[1] https://gitbook.tw/chapters/rewrite-history/remove-and-reorder-commit

[2] https://timmousk.com/blog/git-undo-rebase/