git還原已刪除的分支

由於一時疏忽,錯誤的刪除了承載兩天工作量的開發分支,不過經過仔細覆盤,已恢復原有分支,特此記錄

事故現場還原

以下日誌爲已刪除分支issue#28相關的全部操作日誌:

git reflog |grep '#28'

30b0e5f HEAD@{69}: checkout: moving from issue#28 to master
a3dfaa6 HEAD@{70}: checkout: moving from issue#23 to issue#28
a7f8d04 HEAD@{72}: checkout: moving from issue#28 to issue#23
1d92ae2 HEAD@{74}: checkout: moving from master to issue#28
30b0e5f HEAD@{75}: checkout: moving from issue#28 to master
1d92ae2 HEAD@{76}: checkout: moving from zelda to issue#28
a7f8d04 HEAD@{79}: checkout: moving from issue#28 to issue#23
1d92ae2 HEAD@{81}: checkout: moving from master to issue#28
e705d76 HEAD@{124}: checkout: moving from issue#28 to issue#23
1d92ae2 HEAD@{126}: checkout: moving from issue#23 to issue#28
464dab0 HEAD@{128}: checkout: moving from issue#28 to issue#23
1eb2fef HEAD@{132}: checkout: moving from master to issue#28
1eb2fef HEAD@{134}: checkout: moving from issue#28 to master
1eb2fef HEAD@{136}: checkout: moving from issue#23 to issue#28
464dab0 HEAD@{138}: checkout: moving from issue#28 to issue#23
1eb2fef HEAD@{140}: checkout: moving from master to issue#28
1eb2fef HEAD@{141}: checkout: moving from issue#28 to master
01234ac HEAD@{143}: checkout: moving from master to issue#28
9571cc6 HEAD@{148}: checkout: moving from issue#28 to issue#25
01234ac HEAD@{150}: checkout: moving from issue#25 to issue#28
9571cc6 HEAD@{153}: checkout: moving from issue#28 to issue#25
01234ac HEAD@{155}: checkout: moving from master to issue#28

由日誌分析推演出相關操作歷史:

  1. 在HEAD@{155}處從master上新建了分支issue#28,也就是誤刪除的分支
  2. 在HEAD@{131}處,此時HEAD指向的是issue#28,並且有第1次提交“feat: 資料結構化”
  3. 在HEAD@{130}處,此時HEAD指向的是issue#28,合併了一次master分支,並提交了一次“fix: fix conflict“,這是issue#28分支被刪前僅有的兩次提交
  4. 在HEAD@{129}處,撤銷了某些提交至暫存區的一些修改,工作區恢復到了“fix: fix conflict”的狀態
  5. 在HEAD@{79}至HEAD@{38},issue#28分支有多次切入切出的歷史日誌

僅從git日誌還不夠完全復原事故現場,事後還有以下三點可以確認:

  1. 在HEAD@{38}處也就是issue#23分支上意外強行刪除了(-D)了issue#28
  2. 在HEAD@{79}至HEAD@{38}的過程中的確有大量的修改工作量
  3. 在HEAD@{79}至HEAD@{38}的過程中頻繁切換分支,期間stash了部分未提交的修改,事實上的確如此,在每次切出issue#28分支時,要想既不放棄修改也不提交修改,只能stash封存修改

恢復已刪除分支

在對issue#28分支的操作歷史有了詳細的覆盤後,着手對其進行恢復,主要有以下幾個步驟:

  1. 複製本地git倉庫至另一文件夾

問:既然要恢復了爲何還要複製一份本地倉庫,遠程不是也還有一份嗎
答:主要是爲了保護好第一事故現場,保持一個乾淨的時間線,避免繁雜的記錄干擾恢復工作。複製一份本地倉庫就是1:1複製了事故現場,恢復過程中可能因爲選錯還原點造成恢復失敗或者有大量衝突,如果有多個本地倉庫就可以嘗試多次。

  1. git reflog 查看完整的分支歷史,確定一個還原點

此案例與誤刪分支issue#28相關的最後兩條記錄爲:
30b0e5f (tag: v3.26.27) HEAD@{69}: checkout: moving from issue#28 to master
a3dfaa6 HEAD@{70}: checkout: moving from issue#23 to issue#28
實際上HEAD@{69}所在的分支是master,而HEAD@{70}所在的分支纔是issue#28,故選擇HEAD@{70}作爲還原點。

  1. 從還原點創檢出新分支
git checkout -b issue#28 HEAD@{70}
  1. pop或apply暫存的修改
git stash list
> stash@{0}: WIP on issue#28: 01234ac Merge branch 'issue#26' into 'master'

git stash apply stash@{0}
  1. git status 查看工作區狀態,如有衝突就解決衝突

相關git命令

git reflog與git log 區別

  • git log 只能查看當前分支的log,不能查看已刪除分支的
  • git reflog可以查看所有分支的所有操作記錄(包括已經被刪除的 commit 記錄和 reset 的操作)

git stash

stash主要用於暫存不想提交的修改

  • git stash:暫存當前的修改不提交
  • git stash list:查看已經暫存的歷史
  • git stash pop :彈出最近的一次暫存至工作區,同時從list中刪除
  • git stash apply id:在當前分支應用stash_id 爲id的暫存,但不從list中刪除

小結

  • 刪除分支前一定要謹慎,清理不需要的分支時用-d ,儘量不要直接-D
  • 想辦法禁止自己做一次性大容量提交,這對自己、團隊都很危險。將一個任務切分爲多個細節,按照細節多次提交,每次提交一個完整細節的代碼。
  • 萬一誤刪分支時也不要驚慌失措,仔細覆盤log,找到合適的還原點創建目標分支即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章