Git 机器在切换分支时崩溃

Git 机器在切换分支时崩溃,git,Git,当我的机器崩溃时,我正在切换分支。从本质上讲,Android Studio(大概是Gradle做了一些同步的事情),Itunes和Chrome在windows决定可能进行病毒扫描时(我看到了通知,看着机器冻结,然后上床睡觉)竞相消耗尽可能多的内存。现在,在重新启动之后,我执行的任何git操作都会返回以下消息 fatal: Not a git repository (or any of the parent directories): .git 由于我使用存储库在本地跟踪更改,所以我没有将其推送

当我的机器崩溃时,我正在切换分支。从本质上讲,Android Studio(大概是Gradle做了一些同步的事情),Itunes和Chrome在windows决定可能进行病毒扫描时(我看到了通知,看着机器冻结,然后上床睡觉)竞相消耗尽可能多的内存。现在,在重新启动之后,我执行的任何git操作都会返回以下消息

fatal: Not a git repository (or any of the parent directories): .git
由于我使用存储库在本地跟踪更改,所以我没有将其推送到服务器上,因此无法执行通常的“删除和克隆技巧”。我只有一个
.git
的源代码。有什么方法可以恢复存储库吗?我怀疑
中存在某种文件。git
已使其无效,或者可能存在一个日志文件,详细说明了在机器崩溃之前交换机运行了多远,但我不确定如何继续

下面详细介绍了“我的存储库”文件夹的内容。似乎所有的对象/引用都是呈现的(我已经对它们进行了编辑,因为我怀疑哈希键列表是否相关)

虽然可能与此无关,但我已将git LFS安装到respository中,并主要通过tortoisegit使用它

.git/HEAD
的内容是空白的(Torek先生/女士要求)。调整此值以反映切换前我打开的原始分支会返回以下错误:

error: bad signature
fatal: index file corrupt

好的,第一部分是一个坏的
HEAD
文件,这并不奇怪,因为
HEAD
文件是最活跃的。写一个好的
标题
会让你随后抱怨索引文件不好

该索引包含有关将放入下一次提交的所有文件的信息。最初,这只是当前提交中所有文件的副本。运行
git add file
时,会将文件的新版本(新内容)放入索引中。1如果文件本身是全新的,则该文件将第一次放入索引中。2

因此,索引通常是存储库中第二活跃的文件。但是,幸运的是,除非您
git添加一些内容,然后在工作树中用其他内容重写该内容,或者删除工作树副本,否则您在工作树中仍然有该数据的副本。(自从Git将提交提取到您的工作树之后,您保持不变的文件在另外两个地方有一个良好的副本,即当前提交和工作树。)

这意味着在大多数情况下,您只需删除索引,然后让Git从当前提交中重新生成一个索引:

rm .git/index
git reset       # the default, equivalent to `git reset --mixed HEAD`
git reset
创建一个全新的索引来替换刚刚删除的索引。新索引保存与当前提交相同的文件,即所有
git add
工作都未完成。3但只要工作树中的副本仍然正常,您就可以再次
git add
将它们复制回新索引


1从技术上讲,内容本身作为松散对象进入存储库,而索引只获取新对象的哈希ID。然而,其效果就像文件位于索引中一样

2如果文件在其他提交中,但不是在当前提交中,这可能不是第一次,但发生的情况是索引获取一个新条目,而不是覆盖一些现有条目,因此也足够接近


3如果在旧索引中的任何条目上设置了“假定未更改”或“跳过工作树”位,这些位也将消失,但您可以在新索引上重新设置它们。

您的目录结构是什么?你看到应该保存回购数据的
.git
文件夹了吗?@code学徒我在
.git
文件夹下包含了我的结构。这似乎很得体,所以问题是为什么git会认为我没有
.git
文件夹检查
.git/HEAD
的内容。无论您当时在哪个分支上,该文件都应为
ref:refs/heads/
。如果没有,用这些内容创建它,看看Git是否又高兴了。(注意:
ref:
中的冒号后面只有一个空格,行的结尾是换行符,而不是CRLF,尽管CRLF可能在Windows上工作。)@torek谢谢,这给我带来了一个新的错误需要调查。谢谢,我希望它可以像删除/调整一两个文件一样简单。据我所知,提交实际上是索引中的散列,映射一组散列,表示存储库中的更改(脚注1中的松散对象)。考虑到我在切换分支时,所有分支都变歪了,我没有发现任何“未添加”的文件(如脚注2所示),只有未提交的更改。我是否应该预料到接下来会有什么复杂情况?像是少了一个杂烩什么的?我认为
git reset
可以处理所有的怪癖,但我也会运行
git fsck
。使用
git fsck
是个好主意:它可以确保所有对象的内容都有意义,并匹配它们的哈希ID。至于提交“真正是什么”,你是对的,有一个散列ID,但这是一个Git对象的ID,它包含关于提交的元数据(你的名字、电子邮件、日志消息等),加上父散列ID和树对象散列ID。树对象从文件名映射到blob散列ID(以及可能的子树),blob散列ID提供文件的内容。所有这些都是完整内容的快照。任何物体都可能是松散的或“打包的”,带有[续]。。。这种差异对于正常的Git使用是完全看不见的,但是相当于对象得到了多少压缩。包文件包含许多对象,可以对同一包文件中的其他对象进行增量压缩。打包文件是Git存储更改内容的唯一地方:当您(或Git)通过哈希ID检索对象时,它是一个独立实体。
rm .git/index
git reset       # the default, equivalent to `git reset --mixed HEAD`