git pull是怎么吃我的作业的?


53

我感觉像是校长办公室里的一个孩子,解释那只狗在到期前一天晚上吃了我的作业,但是我盯着脸上的一些疯狂的数据丢失错误,我不知道它是怎么发生的。我想知道git如何吃掉我的整个仓库!我已经把git穿过绞拧器很多次了,而且从未眨眼。我用它来将20 Gig Subversion存储库拆分为27个git存储库,并过滤掉其中的foo以解开混乱,而且它从未对我造成任何损失。reflog总是在那里回落。这次地毯不见了!

从我的角度来看,我所做的只是运行,git pull并且它破坏了我的整个本地存储库。我不是说它“搞乱了已签出的版本”或“我所在的分支”或类似的名称。我的意思是整个事情都没了

这是事件发生时我的终端的屏幕截图:

事件屏幕截图

让我来指导您。我的命令提示符包含有关当前git repo的数据(使用prezto的vcs_info实现),因此您可以查看git repo何时消失。第一个命令足够正常:

  » caleb » jaguar » ~/p/w/incil.info » ◼  zend ★ »
❯❯❯ git co master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

在那里,您可以看到我在“ 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

就像那样,它消失了。如果已超过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).

之后,环顾四周表明我位于一个完全空的目录中。没有。没有'.git'目录,什么也没有。空的

我本地的git版本是2.0.2。这是我的git config中的一些花絮,可能与弄清楚发生了什么有关:

[branch]
        autosetuprebase = always
        rebase = preserve
[pull]
        rebase = true
[rebase]
        autosquash = true
        autostash = true
[alias]
        co = checkout

例如,我已git pull设置为始终进行重新设置而不是合并,因此上面输出的一部分是正常的。

我可以恢复数据。我认为除了一些不重要的存储区没有被推送到其他存储库之外,没有其他git对象,但是我想知道发生了什么

我已经检查过:

  • dmesg或systemd日记中的消息。没有任何关系。
  • 没有迹象表明驱动器或文件系统出现故障(LVM + LUKS + EXT4看起来都很正常)。失物招领中没有任何东西。
  • 我什么也没跑。我上面没有显示的历史记录中没有任何内容,并且在此期间未使用其他终端。没有rm可能在错误的CWD中执行的命令浮动等等。
  • 拨入另一个目录中的另一个git repo不会显示执行git pulls的明显异常。

我还要在这里找什么?


4
@Patrick正如我在问题中已经解释的那样,.git不存在。什么也没做-以前是git根目录,根本没有任何内容。
Caleb 2014年

2
@Alexander拉操作是正常的(其他操作是重新设置而不是合并)。关于强制更新的通知表明,我要从中回购的存储库已被强制按下,从而将其从与上次本地存储库所见位置不同的位置重置。这是正常现象,因为我正在自己的计算机之间同步进行主动开发且经常基于基础的资料,而不是其他开发人员会看到的公共分支。
Caleb 2014年

3
@Caleb在您的shell提示符中包含git分支指示,这意味着形成PS1包括未在您的日志中公开的git命令。他们主要可以更改图片,并且可以成为问题的来源。您应该更新问题,以精确描述您的shell提示的形成方式,运行哪些命令以获取当前分支,并重新考虑它们如何破坏您的存储库。
Netch

2
@Caleb您应该在git development邮件列表上询问;您可以将其编写为错误报告,也可以非正式地询问-还是一样。有些开发人员对git非常了解,他们可以凭直觉判断可能发生了什么。(如果没有,他们将安静地进行讨论。)并且他们知道之前是否曾经发生过。(报告它是报告git错误的“官方”方式)
Volker Siegel 2014年

7
@Wildcard实际上,我一直想把这个问题的答案汇总在一起,因为我确实知道发生了什么。该系统最近刚从睡眠中恢复,并且网络已经进入睡眠状态数天了。在该进程的某个地方,我让一个正在运行的pacman进程试图升级系统上的某些内容。简而言之,事实证明glibc已更新,而git二进制文件已被覆盖。由于它分叉的方式,一个实例最终变得与另一个实例不同,他们吃了彼此的午餐。目录确实是空的(不只是Appar
Caleb,

Answers:


6

是的,git吃了我的功课。所有的。

dd事件发生后,我为该磁盘制作了映像,之后又弄乱了。从系统日志中重建一系列事件,我推断出发生的事情是这样的:

  1. pacman -Syu在此事件发生前几天发出了系统更新命令()。
  2. 长时间的网络中断意味着它不得不重新尝试下载软件包。由于缺乏互联网而感到沮丧,我让系统进入睡眠状态并上床睡觉。
  3. 几天后,系统被唤醒,它再次开始查找和下载软件包。
  4. 在我碰巧与此存储库弄乱之前的某个时候,软件包下载完成了。
  5. 系统glibc安装在git checkout和之后更新git pull
  6. git二进制得到更换后git pull开始,之前完成。
  7. 到了第七日,git一切劳苦都休息了。并删除了世界,其他所有人也都必须休息。

我不知道到底发生什么竞态条件,但在操作过程中换出二进制文件当然不是很好,也不是可测试的/可重复的条件。通常,正在运行的二进制文件的副本存储在内存中,但是git很奇怪,而且它重生成自身版本的方式也很奇怪,我确信这会导致混乱。显然它应该死了而不是摧毁一切,但这就是发生的事情。


1
git可能会失败,因为git是使用differend命令而不是单个二进制文件制作的。一个简单的git拉执行git-fetchgit-rebase或者git-mergegit gc
Ferrybig

2

可能是由于未能定义要删除的文件路径。

您的案例使我想起了美好的一天,当我的自制remove(path)方法尝试删除根文件夹时,因为给定的参数是空字符串,操作系统将其纠正为(!)作为根文件夹。

这可能是类似的git bug。这样:

  1. Rebase命令想要删除一个文件,例如remove(project_folder + file_path)(伪代码)
  2. file_path当时不知何故是空的。
  3. 命令评估为类似 remove(project_folder)

1

幸运的是,您可以使用以下命令解决此问题:

git reset --hard ORIG_HEAD  

当潜在的危险变化开始时,git将您的当前状态保存在ORIG_HEAD中。有了它,您可以撤消合并或变基。

Git手册:撤消合并


4
我认为您没有阅读整个问题。因为没有git meta-data,所以这种修复完全是不可能的。进行这样的重置需要一个现有的.git目录及其中的一些对象。我一无所有。它不仅是一个混乱的工作目录,也不再是任何种类的存储库。
Caleb 2014年

抱歉,我很抱歉。那是非常不寻常的。如果git repo不存在,我想除非您在linux中隐藏文件并为文件提供fs备份,否则将无法恢复。我将删除与我无关的答案。
Routhinator 2014年

是的,我知道这是一个不常见的问题(并且我确实有备份)。我的问题是怎么回事...在git或我的文件系统驱动程序中寻找错误,或在类似操作的中间其他地方吞噬目录。
Caleb 2014年

我也很好奇。讨厌在我的仓库中发生这样的事情。
Routhinator 2014年

-1

好像有人git push --force在此仓库上运行,而您撤消了这些更改。尝试重新克隆存储库,这将使您重新回到干净的工作状态。


1
强制推送重新调整了最后的提交。那不是我拉的(工作目录不再是工作目录!),即使重新克隆也没有任何意义。
Caleb 2014年

4
我认为您无法.git通过强制推送删除某人的目录
Grzegorz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.