1.起因
這個問題要從今天剛遇到的事兒說起,昨晚程式碼出了個烏龍事件,本來正在dev分支進行新功能的開發,但是測試出現的問題是在release 分支上,當時就想到使用stash 將正在開發的dev已經修改的程式碼 暫時存下來,然後切換到master,重新checkout -b 一個新的fix branch進行程式碼修復測試, 但是當我測試完成,fix bug ,push到遠端倉庫後,切換到dev分支進行繼續開發時,
一頓操作猛如虎,結果錯把
git stash pop 0
敲成了
git stash drop 0
當時內心罵出了 what fuck, 心想,這咋辦,難不成要重新憑記憶重來一次,可是關鍵是修改了那麼多的地方,程式碼雖然都是自己寫的,但是重新來寫,心裡是有一萬個不願意啊。於是google了stash 回退, 嘿, 還真有同我一樣曾經手一抖毀所有的經歷。 於是就把這個問題重新整理一下。
2. 問題出現
-
使用
git stash list
顯示所有stash列表
說明:
stash 0,1,2: 說明暫存了三次的快取, 0 表示最新的一條
使用git stash show 0 可以顯示具體修改某一次的詳情, 詳情包括某個分支(dev
),本地快取log md502a2ba5f
-
錯誤使用指令
git stash drop
// 預設刪除的是最近stash save的一次
該指令意思時 將暫存的最新一條快取刪除掉了, 當再次執行git stash list
的時候,最近一次git stash save
已經沒有顯示。★正確使用取出某一次的stash記錄應該使用:
git stash pop 0
-
再次檢視 stash , 發現stash 列表只有兩次快取專案了。
3.修復
git 並沒有刪除包含了我的更改的物件,它只是移除了對它的引用。
為了證明這一點,我使用命令 git fsck,它會驗證資料庫中物件的連線和有效性.
-
使用了引數
--unreachable
,我讓 git-fsck 顯示出所有不可訪問的物件。正如你看到的,它顯示不可訪問的物件。而當我從 stash 中刪除了我的更改之後,表示這些物件是不可以訪問的:
通過 管道符可以過濾出commit的所有丟失的的快取
過濾出來這麼多的不可訪問的物件, 但是並不知道哪一個是剛剛被刪除的那個。 這個排序並不是按時間順序顯示
-
使用
git show commit-log
檢視詳情(需要通過執行命令 git show來搜尋每一個物件。)git show d5ba741a6349936c479aa3f900e53faa3372ae7f
就是它!
ID 號
d5ba741a6349936c479aa3f900e53faa3372ae7f
對應了我的更改。現在我已經找到了丟失的更改,我可以恢復它。其中一種方法是將此 ID 取出來放進一個新的分支,或者直接提交它。
-
恢復,將更改再次恢復應用到dev 分支上。
git stash apply d5ba741a6349936c479aa3f900e53faa3372ae7f
此時分支應該已經恢復到 stash save 之前的狀態
4. 注意
需要重點記住的是 git 會週期性地執行它的垃圾回收程式(gc),它執行之後,使用 git fsck 就不能再看到不可訪問物件了。