恢复因停机导致文件丢失的 git repo
前言ψ(`∇´)ψ
最近这段时间一直在学校大机房写博客,原理是用 Onedrive 同步整个 repo,于是 login 之后直接修改,mkdocs 编译一下直接 push 就可以。
但是 Onedrive 有一个比较致命的问题,对于多文件,它很多时候不能进行即时同步,往往需要手动暂停同步或者退出重进之后才会跟那啥一样自己同步一点。
这个地方已经有人遇到了类似的问题,但是 microsoft 似乎并没有修复这个东西。
很烦,所以就会出现一个问题是,我博客写完了,publish 了,但是我 onedrive 并没有上传,此时又马上要回寝室了,导致文件同步不了,更改丢失。
于是我采取了土办法,直接在非还原盘上存一下没有被同步的文件,这个只需要筛选然后复制一下就行了。
之前已经成功过几次了,但是这次却出现了问题,我开始并没有觉得有啥不对劲,过了一会就出事了。
问题ψ(`∇´)ψ
我复制完之后运行了编译博客的命令:mkdocs serve
,准备看看是不是少了什么东西。
然后发现直接没法编译了,因为我有用一个根据 git 修改记录来自动更新文件修改时间的插件,而它提示我,unable to read git log of xx/yy/zz/aa/bb.cc
(因为当时的会话已经关了,幸好我当时备份了代码以防万一,所以用了错误的代码来演示)
我此时就觉得不对劲,随便开了一个文件看了一下,发现了这样的东西:
很好,原来是我的文件乱码了,看起来是因为我当时复制并没有复制完全,着急着走,直接拉闸断电了。
于是有些文件就没有拷完。
仔细分析发现一个事情是,可能是因为这个,我的 .git
目录下的文件有损坏。
于是我尝试使用 git reset --hard
,然后 git fetch
,之后 git pull
把远程的代码拉取下来。
之后我继续编译了一次。
仍旧是这个问题。
然后我就在搜索引擎里搜索了 如何恢复 git 的文件
先是发现了 git fsck
这个命令,于是我使用它检查了我的 repo:
发现了 git 的文档,阅读之后尝试了一下,但是仍旧没有卵用。
然后注意到这里有几句话:
我推测可能最大的问题是,有一些 commit 文件丢失了,连带着一些文件的 log,于是我先尝试了直接修改它提示的文件,让 git 重新创建 log,然后再运行,发现文件名变化了。
也就是说不止一个,这样下去会比较难受的。
于是我就继续寻找能够解决问题的办法。
再次阅读了文档之后,我有一个想法,他说:
You can recover it the same way, by adding a branch that points to that SHA-1.
也就是说,其实 git 并没有丢失这些 commit,只是从 branch 里移除了(因为文件缺失导致的移除)
所幸记录这个的文件并没有丢失。
所以我打算,把这些丢失的 commit 全部拉出来,直接分别丢到几个 branch 上,然后把这些 branch 直接合并到我的本地 master 分支:
所以我先运行了 git log --pretty=oneline
确实是有 commit 丢失了,于是我再次运行了 git fsck
,然后找到了这些 dangling commit
:
之后我新建了一些 branch,先试试可不可行
1 2 |
|
跑一下 git branch
检查一下:
然后就 git checkout
选择了 master
分支
很好,不能合并,为啥呢,仔细阅读之后发现,因为某些文件丢失,导致这些 commit 也都找不回来了!fk。
之后我就比较困惑,不知道该咋办比较好。
解决方案ψ(`∇´)ψ
最后我只好使用下策 git clone
,这个本来最开始就想到了,但是我想着,这毕竟是在 Onedrive
文件夹上搞,搞出事了到时候我本地数据也没了。
但是仔细一想,这TM不是还有 git repo 吗,就算掉了,远端服务器上还有东西呢!直接复制一下,实在不行重新 remote 都好啊!
于是为了保险,我把已经处理到这步的两个 repo(包含关系)丢进了别的文件夹,然后分别 clone,暴力回退到我昨天晚上的版本(幸好我当时两个 repo 都已经上传了,只是 onedrive 没更新而已)
再次编译,成功了!
总结ψ(`∇´)ψ
我是 shaber。
不过 Onedrive 的这个问题确实是很令我头疼,但是我本身已经很以来基于微软生态的一系列产品了,同步功能确实好用,也不用频繁翻墙,todo 用着也很舒服。
所以我打算去 report 一下这个 bug,目前先将就着用,具体解决就是,既然 OneDrive 对过多文件同步上传速度太慢(我猜测是要记录一些杂七杂八的东西(但不至于这么慢吧)),那我就先只在大机房电脑上改。
然后同步完之后在另外一个机房的主机上编译,然后上传就等那边上传就行,反正那边不断电。
后记ψ(`∇´)ψ
好麻烦………………
(解决问题之后:)
今天晚上发现一个事情,如果 onedrive 不同步了,可以考虑剪切之后在移动回来。
这样 OneDrive 居然就会更新了!(只对 .git
试验了一下,如果都可以我会单独发一篇 blog)