如果我中断了git add命令会发生什么?

5
我运行了以下命令:

git add .

因为有很多文件(>10TB),所以添加需要一些时间。在添加过程中,我不小心删除了一些文件(我需要恢复它们)。如果我在终端中按“Ctrl + C”(中断Git)会发生什么呢?
以下是可能的结果:
  1. 部分文件被添加到Git中(我可以使用git checkout恢复一些文件)。
  2. 没有任何文件被添加到Git中。
谢谢!

它们之前是否已经被提交过? - evolutionxbox
@evolutionxbox 不,这是在 git init 之后的第一次。 - nilesh
如果它们没有被添加,AKAIK它们将会消失。 - evolutionxbox
@evolutionxbox 如果 git add 仍在运行,我想知道如果我中断 git add,那些可能已添加的文件会发生什么。 - nilesh
你为什么要把超过10TB的东西放在一个Git仓库里? - 1615903
1个回答

6
在我的实验中,如果 git add 被中断,就不会在索引中留下任何内容(您可以使用git status 确认此情况),但它确实会在其内部结构中保留任何创建的 blob,因此可能会有一些文件可以恢复。请参阅https://git-scm.com/book/zh/v2/Git-内部原理-Git-数据对象了解有关从 Git 内部 blob 中提取文件的信息。
我通过这种方式恢复了一个文件:
> find .git/objects -type f
...
.git/objects/ac/a6e96aaf9492a2ee8f9ef51f0197ad56436fd4
...

> git cat-file -p aca6e96aaf9492a2ee8f9ef51f0197ad56436fd4 > file1

请注意,块ID是目录名称ac加上块文件名a6e96...以形成aca6e96...
通过这种方式,Git为我提供了一个文件的内容。不过,这样使用起来并不方便,因为您只能获得文件内容而没有文件名。如果您有机会进行提交,则文件名将存储在索引中和更持久的结构中,但是对于在中断的git add期间创建的块,该信息尚不可用。
以下是一个脚本,它将列出一个文件中的所有块,并带有分隔符,这可能会使您的生活更加轻松:
文件list-blobs.pl
#!/usr/bin/perl

open BLOBS, "find .git/objects -type f |";
while (<BLOBS>) {
   chop;
   s#.*(..)/#\1#;
   print "BLOB $_\n";
   system("git cat-file -p $_");
}

运行

chmod +x list-blobs.pl    
list-blobs.pl | less

你将看到,Git在中断git add之前实际存储在blob中的对象。

更简单的方法是:使用https://github.com/ethomson/git-recover,它是作者Edward Thomson在下面评论中分享的。


实际上,我已经从本地删除了文件,所以想知道是否可以从git中恢复。 git status 没有显示任何添加的内容,因为 git add 仍在运行,而且由于文件大小超过10TB,我怀疑这将需要很长时间。 - nilesh
1
好吧,我之前说的不太准确:我尝试了你的情况,当我开始然后中断一个 git add . 操作时,.git 目录会变得更大。所以这些 blob 已经被创建并存储在 .git 中。它们能从那里恢复吗?我认为我们需要一位更深入了解 Git 的专家来回答这个问题,但也许可以。 - joanis
1
我在这个项目上花费了太多时间,因为它很有趣……刚刚添加了一些关于检查存储在 .git/objects 中 blob 的信息。 - joanis
1
当我第一次尝试使用cat-file时,我遇到了这个问题。在我的情况下,问题出在你需要将两个字符的目录名称添加到blob文件名的开头。因此,.git/objects/ac/1234...是blob ac1234...。实际上,你的字符串只有38个字符,但blob ID有40个字符,所以你遇到了同样的问题。 - joanis
@Edward Thomson: 感谢您指出git-recover,这是一个非常好的工具! - joanis
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接