我加了一些文件的索引,但随后被错误我删除他们git reset --hard
。 如何恢复呢? 事情是这样的:
- 我添加使用的所有文件
git add .
- 然后,我犯
- 当我检查了状态,仍然有未包含在从添加提交文件,这是奇怪的
- 我再次添加未跟踪文件和它的工作这段时间
- 但我想要的一切是在1单的提交,所以我抬起头怎么unstage我刚才犯
- 我以前
git reset --hard HEAD^
-显然坏主意,所有的文件被删除 - 所以后来我用
git reflog
找我已关闭 - 然后我用
git reflog ______
回到我的最后一次提交。 - 然后我用
git reset HEAD
到unstage提交(是我应该做最初),但我添加的文件(见上文)在提交之后仍然走了。
我如何获得这些文件回来?
首先,让你的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 -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