Git 操作之“git stash内容误删找回”

最近我在开发中遇到这么一个问题:某次的开发内容使用git stash命令暂存了工作现场,之后手残直接删除了暂存的这次记录和内容。

第一步: 使用git fsck --unreachable命令查找所有unreachable的记录

unreachable:
Print out objects that exist but that aren’t reachable from any of the reference nodes.
这条命令会打印出所有不能从任何索引节点访问但是确存在的对象,回车之后我们会看到如下的显示:

  • git fsck --unreachable输出
    Git 操作之“git stash内容误删找回”
  • 如上图所示,大概有三种类型的内容,blob、tree和commit。我们这样看的话是看不出任何有用信息的,我们需要另外一条命令将其内容show出来。

第二步:使用git show命令显示记录内容

Shows one or more objects (blobs, trees, tags and commits).

  • git show后面跟上要show的id,就可以展示这个id所对应的blob,tree,tag和commit。比如:git show eba0c76fxxxxxx。
  • 备注: 这些id所对应的记录并不是有序的,如果想要找到之前误删的内容,需要我们一条条的去show出这些内容,然后判断是否是要找回的。
    • 一是我们只需要关心commit类型的内容,这些才是我们保存过或者提交过的内容;
    • 二是show出来的内容是有日期的,我们只要能大概记住误删内容的保存或提交日期,那么找起来自然轻松很多。
    • 三通过linux脚本批量输出到文件:sh xx.sh > a.log。然后打开a.log 文件搜索自己修改内容,找到对应的ID。
      #!/bin/bash
      
      # 把git fsck --unreachable的输出,用sublime或者其他编辑器,批量编辑成单行的字符串。
      # 每个ID之间用空格分割。
      commits="1dfb1f1d36aa7b8a93d735bde987258e8f673667 e3e1078cb8e0d4a1c077f9b0c9ae6723f363c85f"
      
      for i in $commits
      do
          git show $i
          # 每条记录用--- 分割开
          echo "------------------------------------------\n"
      done
      

第三步:使用git stash apply命令恢复记录内容

  • 根据第上一步找到我们所要恢复内容的id,使用git stash apply进行恢复。
  • 注意:
    git stash apply只能恢复commit类型的记录,如果使用这条命令来恢复blob,tree或tag可能会报错。所以,在a.log搜索的时候,注意找commit 类型的ID,再去 apply

总结

  • blob,tree,tag和commit都代表了什么含义,各有什么作用:
  • 每个object包含三个部分:类型,大小和内容。大小就是指内容的大小,内容取决于对象的类型,有四种类型的对象: blob,tree,tag和commit。
    1. blob 用来存储文件数据,通常是一个文件
    2. tree 有点像一个目录,它管理一些tree或blob,就像文件和子目录
    3. tag 标签,用来标记某一次的commit
    4. commit 只指向一个tree,它用来标记项目某一个特定时间点的状态。它包括一些关于时间点的元数据,比如时间戳、最近一次提交的作者,指向上次提交的指针等等。

相关文章: