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 就不能再看到不可訪問對象了。