深度思维者

永远年轻,永远热泪盈眶

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. 问题出现

  1. 使用git stash list 显示所有stash列表

    说明:
    stash 0,1,2: 说明暂存了三次的缓存, 0 表示最新的一条
    使用git stash show 0 可以显示具体修改某一次的详情, 详情包括某个分支(dev),本地缓存log md5 02a2ba5f

  2. 错误使用指令

    git stash drop // 默认删除的是最近stash save的一次

    该指令意思时 将暂存的最新一条缓存删除掉了, 当再次执行 git stash list的时候,最近一次git stash save 已经没有显示。

    正确使用取出某一次的stash记录应该使用:git stash pop 0

  3. 再次查看 stash , 发现stash 列表只有两次缓存项目了。

3.修复

git 并没有删除包含了我的更改的对象,它只是移除了对它的引用。

为了证明这一点,我使用命令 git fsck,它会验证数据库中对象的连接和有效性.

  1. 使用了参数 --unreachable,我让 git-fsck 显示出所有不可访问的对象。

    正如你看到的,它显示不可访问的对象。而当我从 stash 中删除了我的更改之后,表示这些对象是不可以访问的:

    通过 管道符可以过滤出commit的所有丢失的的缓存

    过滤出来这么多的不可访问的对象, 但是并不知道哪一个是刚刚被删除的那个。 这个排序并不是按时间顺序显示

  2. 使用 git show commit-log 查看详情(需要通过执行命令 git show来搜索每一个对象。)

    git show d5ba741a6349936c479aa3f900e53faa3372ae7f

    就是它!

    ID 号d5ba741a6349936c479aa3f900e53faa3372ae7f 对应了我的更改。

    现在我已经找到了丢失的更改,我可以恢复它。其中一种方法是将此 ID 取出来放进一个新的分支,或者直接提交它。

  3. 恢复,将更改再次恢复应用到dev 分支上。

    git stash apply d5ba741a6349936c479aa3f900e53faa3372ae7f

    此时分支应该已经恢复到 stash save 之前的状态

4. 注意

需要重点记住的是 git 会周期性地执行它的垃圾回收程序(gc),它执行之后,使用 git fsck 就不能再看到不可访问对象了。

posted @ 2021-06-24 22:09  failymao  阅读(1481)  评论(0编辑  收藏  举报