git stash回退
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 就不能再看到不可访问对象了。