如何从 git reset --hard 中拯救代码

上个周末遇到了一个这样的场景node

场景

本身写了大半天的一个小东西的代码,目录结构大概以下
node_modules
src
  - ...files
test
  - test.js
package.json

睡前原本准备上传到github仓库git

  • git init
  • git add -A

发现忘记添加.gitignore,把node_modules文件都add进去了
因而手贱输入了git reset --hardgithub

而后发现...目录里的东西所有没了(只剩下.git/文件架),shell

当时个人心里
心里json

挽救

心急如焚懊悔不已的我,通过查阅相关资料,仍是找到了一些拯救代码的方法异步

因为每次git命令进行操做时git都会对相关文件进行快照,并经过必定形式把信息保存再.git/目录下。ui

因为此前我使用过git add -A命令,所以当文件被放进暂存区时,快照信息对象就已经保存了,而实用git reset --hard以后,这些对象就变成了悬空文件对象(dangling blob)。spa

咱们可使用git fsck命令显示他们.net

git fsck:用于验证当前git仓库数据的有效性和一致性,可以显示那些"丢失"的commitblob(文件)、tree等。3d

咱们能够经过如下命令
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")

咱们获得一大堆blob的hash ID

unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
...

接下来使用git show就能显示这些对象的内容了,例如git show 907b308

自动还原

可是因为我曾经添加的文件实在太多node_modules里的文件可能有上千个,所以对逐个ID进行git show肉眼筛选是很是不科学。

所以我写了个简单的nodejs脚本(由于我比较熟悉),筛选还原那些我须要的文件。

首先使用git fsck把hash ID都存到一个文件里
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > allhashes

"use strict";

const fs = require("fs");
const shelljs = require("shelljs");
const through = require("through2");

let buf = fs.readFileSync("./allhashes")
buf = buf.toString();
let hashes = []
buf.replace(/dangling blob (\w+)/gi,function (matached, hash) {
    hashes.push(hash)
});

let all = hashes.length;
let left = all;
hashes.forEach(hash=>{
    let fullContent = ""
    let stdout = shelljs.exec("git show "+hash,{silent:true}).stdout;
    let input = through();
    console.log((left--)+"/"+all);
    //TODO:through2原来是为了处理stdout流的异步数据引入的,当前同步过程下不须要
    input.pipe(through((buf,_,next)=>{
        fullContent = fullContent+buf.toString();
        next(null,buf)
    },flush=>{
        if (matchContent(fullContent)){
            fs.writeFile("./objects/"+hash,fullContent)
        }
        flush()
    }))

    input.push(stdout);
    input.push(null);
})

function matchContent(content){
    // ... 匹配规则
}

因而通过几分钟的执行,我找回了个人代码
图片描述

参考连接

相关文章
相关标签/搜索