2 回答
TA贡献1815条经验 获得超12个赞
首先,完整备份您的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
这不会取消暂存此提交,但会取消暂存索引中所有已暂存(但未提交)的更改。最初(第一步),您想说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>
将打印文件内容,因此您可以验证是否具有正确的对象。对于Blob,您可以使用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
它将所有更改转移到跟踪文件中。要跟踪新文件,最好明确地指定它们。
TA贡献2065条经验 获得超13个赞
我有一个类似的问题,但是我的回购中有很多悬挂的斑点和树木,所以我最终用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
- 2 回答
- 0 关注
- 593 浏览
添加回答
举报