恢复被添加到索引,但然后取出用git的重置文件恢复被添加到索引,但然后取出用git的重置文件(Rec

2019-05-16 14:17发布

我加了一些文件的索引,但随后被错误我删除他们git reset --hard 。 如何恢复呢? 事情是这样的:

  1. 我添加使用的所有文件git add .
  2. 然后,我犯
  3. 当我检查了状态,仍然有未包含在从添加提交文件,这是奇怪的
  4. 我再次添加未跟踪文件和它的工作这段时间
  5. 但我想要的一切是在1单的提交,所以我抬起头怎么unstage我刚才犯
  6. 我以前git reset --hard HEAD^ -显然坏主意,所有的文件被删除
  7. 所以后来我用git reflog找我已关闭
  8. 然后我用git reflog ______回到我的最后一次提交。
  9. 然后我用git reset HEAD到unstage提交(是我应该做最初),但我添加的文件(见上文)在提交之后仍然走了。

我如何获得这些文件回来?

Answer 1:

首先,让你的Git仓库的完整备份!

当你git add一个文件,git会创建一个BLOB出这个文件的内容,并把它添加到它的数据库对象( .git/objects/??/* )。

让我们来看看你的命令,一个接一个:

我添加使用Git添加的所有文件。

$ git add .

这将包含在当前目录下的所有文件及其子目录添加到Git的对象数据库。 从匹配模式未追踪文件.gitignore文件不会被添加。 树中的文件也将被写入。 请参阅我的回答结束。

然后,我犯

$ git commit -m'added all files'

这将谱写新的提交对象的对象数据库。 此承诺将引用一棵树。 树引用斑点(文件)和其他树木(子目录)。

当我检查了状态,仍然有未包含在从添加提交文件,这是奇怪的

$ git status

我能想到的两种方案,其中发生这种情况:一些修改您的文件或你背后添加了新的文件。

我再次添加未跟踪文件和它的工作这段时间

$ git add .

我假设你使用相同的add再次命令,在步骤1中。

但我想要的一切是在1单的提交,所以我抬起头怎么unstage我刚才犯

我会告诉你这个答案的最后一个更好的方法,它不需要用户发出潜在危险reset

我以前的git的复位 - 硬头^ - 显然坏主意,所有的文件被删除

$ git reset --hard HEAD^

此命令将设置你的当前工作的树和指数正好在提交HEAD^ (倒数第二个提交)。 换句话说,它会放弃任何本地未提交的更改和分支指针移到后面一个提交。 它不碰未跟踪文件。

所以后来我用的git reflog了找我已关闭

$ git reflog

这表明,最近签出(等同于最后提交git reflog HEAD )。 如果您指定一个分支的名字,它会告诉你最后一次提交这个分支指向最近。

然后我用的git reflog了__回到我的最后一次提交。

不知道这一个。 git reflog是(主要)只读命令,不能使用“重回”来提交。 你可以只用它,发现犯了分支(或HEAD )指出。

然后我用git的重置头unstage提交(是我应该做最初),但我添加的文件(见上文)在提交之后仍然走了。 $ git的复位HEAD

这不会unstage这种承诺,但它会unstage索引中的所有上演(但是未提交)更改。 本来(第一步),你想说的话git reset HEAD^ (或git reset --mixed HEAD^ ) -这将使你的工作树不动,但设定的指标相匹配的树指出,在提交名为HEAD^


现在,找回你的文件,你必须使用git fsck --full --unreachable --no-reflog 。 它会扫描在Git的对象数据库中的所有对象,并进行可达性分析。 你想寻找blob对象。 还应该有一个tree对象,描述你的第二个后的状态git add .

git cat-file -p <object hash>将打印的文件内容,这样你就可以验证是否有合适的对象。 对于斑点,你可以使用IO重定向写的内容,以正确的文件名。 对于树,你必须使用Git命令( git read-tree )。 如果只有几个文件,你最好直接写他们的文件。


一些注意这里:

如果你想将文件添加到上次提交(或编辑提交信息),你可以简单地用git commit --amend 。 它基本上是围绕着包装git reset --soft HEAD^ && git commit -c HEAD@{1}

此外,它几乎从来没有使用一个好主意git add . 。 通常情况下,你只需要使用它的第一次,当你创建一个新的存储库。 更好的选择是git add -ugit commit -a ,这将启用所有更改跟踪文件。 要跟踪新文件,明确地更好指定它们。



Answer 2:

我也有类似的问题,但我有很多在我的回购晃来晃去斑点和树木的,所以我结束了与过滤grep所有晃来晃去的斑点的输出和打印匹配的人。 假设${UNIQUE_CODE}是一些代码,不可重复,可以在索引中,那么这应该给你你正在寻找的斑点的哈希过的文件:

for b in $(git fsck --lost-found | grep blob | awk '{print $3}'); do git cat-file -p $b | grep -q ${UNIQUE_CODE} && echo $b; done


文章来源: Recover files that were added to the index but then removed by a git reset