如何從 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){
    // ... 匹配規則
}

因而通過幾分鐘的執行,我找回了個人代碼
圖片描述

參考連接

相關文章
相關標籤/搜索