恢复已添加到索引但通过git重置删除的文件
我在索引中添加了一些文件,但后来我错误地用git reset --hard
删除了它们。 我如何恢复它们? 以下是发生的事情:
git add .
添加了所有文件git add .
git reset --hard HEAD^
- 很明显,所有文件都被删除了 git reflog
来查找我离开的位置 git reflog ______
返回到上次提交。 git reset HEAD
取消提交(原本应该执行的操作),但提交后添加的文件(请参见上文)仍然消失。 我如何获取这些文件?
首先,对你的Git仓库进行完整备份!
当你git add
一个文件时,git会从这个文件的内容中创建一个blob,并将它添加到它的对象数据库( .git/objects/??/*
)。
让我们一个一个地看看你的命令:
我使用git add添加了所有文件。
$ git add .
这会将当前目录及其子目录中包含的所有文件添加到Git的对象数据库中。 未匹配的.gitignore
文件匹配模式的文件将不会被添加。 树文件也将被写入。 请参阅我的答案的结尾。
然后我承诺
$ git commit -m'added all files'
这会将新的提交对象写入对象数据库。 这个提交会引用一棵树。 树引用blob(文件)和其他树(子目录)。
当我检查状态时,仍然存在没有包含在添加提交中的文件,这很奇怪
$ git status
我可以想到发生这种情况的两种情况:修改您的文件或在您背后添加新文件。
我再次添加了未跟踪的文件,并且这次它工作
$ git add .
我假设你再次使用了相同的add
命令,如第1步所示。
但我希望所有事情都能在一次单独提交中进行,因此我查找了如何取消我刚刚承诺的内容
我会告诉你一个更好的方式,在这个答案的结尾,这不需要用户发出潜在的危险reset
我用git reset --hard HEAD ^ - 很明显,所有文件都被删除了
$ git reset --hard HEAD^
这个命令会将你当前的工作树和索引设置为提交HEAD^
(倒数第二个提交)。 换句话说,它将丢弃任何本地未提交的更改并将分支指针移回一个提交。 它不会触及未跟踪的文件。
所以我用git reflog来查找我离开的地方
$ git reflog
这显示了最近检出的最后一个提交(与git reflog HEAD
相同)。 如果您指定了分支名称,它将向您显示此分支最近指向的最后一个提交。
然后我使用git reflog __返回上次提交。
不知道这个。 git reflog
(大部分)是只读命令,不能用于“提交”提交。 您只能使用它来查找指向分支(或HEAD
)的提交。
然后我使用git reset HEAD取消提交(原本应该执行的操作),但提交后添加的文件(请参见上文)仍然消失。 $ git reset HEAD
这不会取消这个提交,但它会取消索引中所有已执行的(但未提交的)更改。 最初(第1步),你想说git reset HEAD^
(或者git reset --mixed HEAD^
) - 这会让你的工作树保持原样,但是将索引设置为匹配由HEAD^
指定的提交所指向的树HEAD^
。
现在,为了取回你的文件,你必须使用git fsck --full --unreachable --no-reflog
。 它将扫描Git对象数据库中的所有对象并执行可达性分析。 你想寻找blob
对象。 还应该有一个tree
对象,描述第二个git add .
后的状态git add .
git cat-file -p <object hash>
会打印文件内容,所以你可以验证你是否有正确的对象。 对于blob,您可以使用IO重定向将内容写入正确的文件名。 对于树木,你必须使用git命令( git read-tree
)。 如果只有几个文件,最好直接写入文件。
这里有几个注意事项:
如果你想添加文件到最后一次提交(或编辑它的提交信息),你可以简单地使用git commit --amend
。 它基本上是git reset --soft HEAD^ && git commit -c HEAD@{1}
的包装。
另外,使用git add .
几乎不是一个好主意git add .
。 通常,当您创建新的存储库时,您只希望第一次使用它。 更好的选择是git add -u
, git commit -a
,它将对所有跟踪文件进行更改。 要跟踪新文件,最好明确地指定它们。
我有一个类似的问题,但我的回购中有很多晃来晃去的斑点和树,所以我最后用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
链接地址: http://www.djcxy.com/p/23499.html
上一篇: Recover files that were added to the index but then removed by a git reset
下一篇: Undo a git pull