Cal*_*leb 53 debugging git data-recovery
我感觉就像校长办公室里的一个孩子,解释说我的作业在到期前一天晚上被狗吃掉了,但我正盯着脸上的一些疯狂的数据丢失错误,我无法弄清楚它是怎么发生的。我想知道 git 怎么会吃掉我的整个存储库!我已经多次将 git 放入绞拧器中,它从不眨眼。我用它将 20 Gig Subversion 存储库拆分为 27 个 git 存储库,并将 foo 过滤分支出来以解决混乱问题,并且它从未在我身上丢失过一个字节。reflog 总是可以依靠的。这次地毯不见了!
从我的角度来看,我所做的只是运行git pull
,它破坏了我的整个本地存储库。我的意思不是说它“弄乱了签出的版本”或“我所在的分支”或类似的东西。我的意思是整件事都没有了。
这是事件发生时我的终端的屏幕截图:
让我带你了解一下。我的命令提示符包含有关当前 git 存储库的数据(使用 prezto 的 vcs_info 实现),因此您可以查看 git 存储库何时消失。第一条命令就够正常了:
» caleb » jaguar » ~/p/w/incil.info » ? ? zend ? »
??? git co master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Run Code Online (Sandbox Code Playgroud)
在那里你可以看到我在 'zend' 分支上,并检查了 master。到现在为止还挺好。您将在我的下一个命令之前的提示中看到它成功切换了分支:
» caleb » jaguar » ~/p/w/incil.info » ? ? master ? »
??? git pull
remote: Counting objects: 37, done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 37 (delta 25), reused 0 (delta 0)
Unpacking objects: 100% (37/37), done.
From gitlab.alerque.com:ipk/incil.info
+ 7412a21...eca4d26 master -> origin/master (forced update)
f03fa5d..c8ea00b devel -> origin/devel
+ 2af282c...009b8ec verse-spinner -> origin/verse-spinner (forced update)
First, rewinding head to replay your work on top of it...
>>> elapsed time 11s
Run Code Online (Sandbox Code Playgroud)
就这样它消失了。如果超过 10 秒,则经过时间标记在下一个提示之前输出。除了正在倒带重放的通知之外,Git 没有给出任何输出。没有迹象表明它完成了。
下一个提示不包含有关我们所在的分支或 git 状态的数据。
没有注意到它失败了,我无意中尝试运行另一个 git 命令却被告知我不在 git repo 中。注意 PWD 没有改变:
» caleb » jaguar » ~/p/w/incil.info »
??? git fetch --all
fatal: Not a git repository (or any parent up to mount point /home)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
Run Code Online (Sandbox Code Playgroud)
之后环顾四周,发现我在一个完全空的目录中。没有。没有“.git”目录,什么都没有。空的。
我的本地 git 版本为 2.0.2。以下是我的 git 配置中的一些花絮,可能与弄清楚发生了什么有关:
[branch]
autosetuprebase = always
rebase = preserve
[pull]
rebase = true
[rebase]
autosquash = true
autostash = true
[alias]
co = checkout
Run Code Online (Sandbox Code Playgroud)
例如,我已git pull
设置为始终执行变基而不是合并,因此上面的部分输出是正常的。
我可以恢复数据。我认为除了一些没有被推送到其他存储库的不重要的隐藏之外,没有任何 git 对象,但我想知道发生了什么。
我已经检查过:
rm
可能在错误的 CWD 中执行的命令,等等。git pull
s没有明显异常。我还应该在这里寻找什么?
是的,git
吃了我的作业。所有的。
我dd
在事件发生后制作了这张磁盘的图像,后来又把它弄乱了。从系统日志中重建一系列事件,我推断发生的事情是这样的:
pacman -Syu
) 已在此事件发生前几天发出。git checkout
在git pull
.git
二进制得到更换后git pull
开始,之前完成。git
就歇了一切劳碌。并删除了世界,所以其他人也不得不休息。我不知道究竟是什么竞争条件导致了这种情况发生,但是在操作中间换出二进制文件肯定不是很好,也不是可测试/可重复的条件。通常,正在运行的二进制文件的副本存储在内存中,但git
很奇怪,而且关于它重新生成自身版本的方式,我肯定会导致这种混乱。显然它应该死而不是摧毁一切,但这就是发生的事情。