记一次git仓库损坏的经历
背景
我的manjaro Linux滚动更新后nVidia显卡HDMI输出出现了问题,暂时无法解决,因此开发环境切换到Windows.环境搭建的很顺利.
问题的产生
今日在执行git commit时提交的信息中包含了大量垃圾信息(换行符从LF换掉CRLF)又没有注意到,提交后发现commit message与我预想的不对,随后又发现所有行后面都加上了Windows的换行符,因此打算撤回这次commit,更改换行符到LF再重新commit.于是终端中执行.
git log
git reset --mixed <commit-hash>
理论上执行很快就能完成,但不巧的是Windows卡住然后蓝屏了,经调查蓝屏原因是nvme SSD接口故障.硬盘错误可能会导致数据损坏,果然,再打开仓库时,git说这不是一个有效的git仓库
$ git status
fatal: 不是一个 git 仓库(或者向上递归至挂载点 /mnt 的任何祖先目录)
停止在文件系统边界(未设置 GIT_DISCOVERY_ACROSS_FILESYSTEM)
然而.git
文件夹还在那里,推测git仓库的部分文件损坏.由于最近两次的commit都没有提交,因此需要从这些文件中找回写过的代码,要不然就要重写.
查看损坏的repo中workspace中的文件,全部变成了乱码的二进制文件.找到Linux中的历史版本,使用diff工具比较.git
,objects
文件夹即为数据文件, 不要更改, 查找其他乱码的文件, 发现以下文件损坏, 使用旧仓库的覆盖.
- .git/index
- .git/config
- .git/HEAD
.git/HEAD
的内容为ref: refs/heads/master
, 打开正常仓库的.git/refs/heads/master
, 里面为commit-hash, 打开损坏仓库的.git/logs/refs/heads/master
, 发现内容正常, 为commit的历史, 将最后一次的hash复制到.git/refs/heads/master
, 再执行git reset --hard <commit-hash>
, 文件成功恢复.
提醒
.git
中的文件在正常情况下不要手动修改, 除非出现这种事故.
本地仓库commit后就应该push到远程仓库, 防止文件损坏.