问题描述:

git commit 时 只上传了部分文件,但是直接进行了--hard版本穿梭,导致工作区、暂存区的文件都消失或被覆盖的问题。

我当时将所有文件都add到了暂存区,但只commit了一个pom.xml文件(当时脑子不知道怎么想的),随后进行了版本回退,reset --hard 到了一个只有.idea文件夹的初始版本,导致我项目中的src文件夹、target文件夹都消失了(超多文件,心态直接炸裂),并且仓库中不存在 拥有src文件夹的版本,无法通过git reflog和reset 解决

git reset --hard [版本哈希值]  会撤销工作区中所有未提交的修改内容, 将暂存区与工作区都回到上一次版本 ,并删除之前的所有信息提交。(慎用)

若此时暂存区内有未commit的文件,会直接丢失。

解决方案:

前提:文件必须add到暂存区过!没add神都救不了你!   .git文件夹也必须没有改动过

如果 git reflog 可以找到拥有丢失的文件的版本,可以直接git reset 版本号 回退,但本问题明显不是这么简单可以解决的。

核心命令:git fsck --lost-found    git read-tree --prefix=lib 文件哈希   git checkout --lib

首先输入:

git fsck --lost-found

git fsck --lost-found 可以通过一些神奇的方式把曾经add到暂存区过的文件以某种算法算出来加到 .git/lost-found 文件夹里,直接去文件夹里找便可以找到丢失的特殊文件

输出记录:

可以看到第二列 blob 、tree 、commit 为文件类型,第三列为文件名(哈希值)

这是git的底层文件对象

commit数据结构在每次提交之后都会生成一个,当我们进行commit之后,首先会创建一个commit组件,之后创建一个tree组件,把所有的文件信息都储存在里面,每个blob代表一个文件,都可以在tree里找到

blob组件并不会对文件信息进行存储,而是只对文件的内容进行记录,文件信息存储在tree里

通俗的讲,blob是文件,可以直接打开看到其中的文字,tree为文件夹,git show可以看到目录结构但只有文件名

git show 文件名

 tree类型可以通过git ls-tree 文件哈希 来列出其下面的文件名和id

git ls-tree 文件名

 既然tree内部的文件的哈希都拿到了,就可以一层一层地拿到文件的内容了

但是我丢掉的文件实在是太多了,让我一层一层的取,一层一层的复制粘贴?目录结构也要自己新建?开玩笑!

当时的我真准备“破釜沉舟”开肝了,后来搜索半天又查阅官方文档,终于找到了一个git的命令!!!

Git的子树合并

使用子树合并,可以实现一个项目中引用其他项目的数据,并建立跟踪关联。

官方文档:git read-tree --help

简而言之,使用git read-tree可以解析tree文件并存入index暂存区

git read-tree --prefix=lib 要解析的tree文件哈希值

此命令会将tree递归解析,将其关联的所有目录树以子目录形式添加到master分支

接下来 git status打印状态

可以看到它将此tree文件所指向的文件全部写入了暂存区,但又将工作区删了个干净 ,所以你执行完是看不见lib文件夹的。

它只是更新了index,所以还要加上

git checkout --lib

来更新工作区的lib目录内容

此时奇迹便发生了!

目录中多了个lib文件夹,里边便是那丢失的全部文件!

问题描述:git commit 时 只上传了部分文件,但是直接进行了--hard版本穿梭,导致工作区、暂存区的文件都消失或被覆盖的问题。我当时将所有文件都add到了暂存区,但只commit了一个pom.xml文件(当时脑子不知道怎么想的),随后进行了版本回退,reset --hard 到了一个只有.idea文件夹的初始版本,导致我项目中的src文件夹、target文件夹都消失了(超多文件,心态直接炸裂),并且仓库中不存在 拥有src文件夹的版本,无法通过git reflog和reset 解决原因 我们在使用git管理代码时通常要提交和拉取代码,但是某些时候存在误操作的行为。例如代码还没提交就做了checkout、push动作,导致写了几天的代码没有备份就丢失或者被覆盖了。 恢复前提 在执行git checkout master或者git push命令前,执行过commit命令git commit -m "xxx",git工具才能给你记录你的版本变化(本地的),否则丢失代码可能无可挽救。 (1)查看历史本地git版本:git reflog。运行结果如下图所示,现在需要回滚到ch 提交修改的内容到暂存区中,不要push,这时使用 git reset --hard 将暂存区中的提交撤销,并且本地修改也回撤掉 这时内容已经改回之前的了,不小心把自己改了的代码也撤销了,这时需要回。 使用命令:git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)
哎?以前这个文件是什么样的呢?返回上一版本看看吧,于是git reset --hard xxxxx便邪恶地运行了 好了,看完了,我该干活了,回我的最新版本吧 沃德天!!!!!!!!头皮怎么有点发麻?我的文件呢???把桌子翻遍了,都不到我亲爱的文件的影子,我可是没有add,也没有commit啊,咋办? 于是,上网查呗,一溜达不要紧,都说完了,要重新写,更麻了! 偶然间看到了一个博文,抱着试