Jef*_*ley 10 git git-add git-reset git-commit git-reflog
我在索引中添加了一些文件但是后来我用它删除了它们git reset --hard.我该如何恢复它们?这是发生的事情:
git add .git reset --hard HEAD^- 很明显,所有文件都被删除了git reflog找到我离开的地方git reflog ______回到上一次提交.git reset HEAD取消提交(我应该最初做的)但是我提交后添加的文件(见上文)仍然没有.如何获取这些文件?
kni*_*ttl 21
首先,对Git存储库进行完整备份!
当你git add是一个文件时,git会用这个文件的内容创建一个blob并将它添加到它的对象数据库(.git/objects/??/*)中.
让我们一个一个地看看你的命令:
我使用git add添加了所有文件.
$ git add .
Run Code Online (Sandbox Code Playgroud)
这会将当前目录及其子目录中包含的所有文件添加到Git的对象数据库中..gitignore不会添加与文件中的模式匹配的未跟踪文件.树文件也将被写入.请看我的答案结束.
然后我承诺了
$ git commit -m'added all files'
Run Code Online (Sandbox Code Playgroud)
这将向对象数据库写入新的提交对象.此提交将引用单个树.树引用blob(文件)和其他树(子目录).
当我检查状态时,仍然有来自add的提交中没有包含的文件,这很奇怪
$ git status
Run Code Online (Sandbox Code Playgroud)
我可以想到发生这种情况的两种情况:修改你的文件或在你背后添加新文件的东西.
我再次添加了未跟踪的文件,这次工作正常
$ git add .
Run Code Online (Sandbox Code Playgroud)
我假设您add再次使用相同的命令,如步骤1中所示.
但我希望一切都在一次提交中,所以我抬头看看如何取消我刚刚提交的内容
在这个答案的最后,我会告诉你一个更好的方法,这不需要用户发出潜在的危险 reset
我用git reset --hard HEAD ^ - 显然很糟糕,所有文件都被删除了
$ git reset --hard HEAD^
Run Code Online (Sandbox Code Playgroud)
此命令将您当前的工作树和索引设置为提交HEAD^(第二次提交).换句话说,它将丢弃任何本地未提交的更改并将分支指针移回一个提交.它不会触及未跟踪的文件.
所以我用git reflog找到了我离开的地方
$ git reflog
Run Code Online (Sandbox Code Playgroud)
这显示了最近检出的最后一次提交(与之相同git reflog HEAD).如果指定分支名称,它将显示此分支最近指向的最后提交.
然后我用git reflog __回到我上一次提交.
不确定这个.git reflog(大部分)是只读命令,不能用于"返回"提交.您只能使用它来查找提交分支(或HEAD)指向的分支.
然后我使用git reset HEAD来取消提交(我应该最初做的)但是我提交后添加的文件(见上文)仍然没有.$ git reset HEAD
这不会取消暂存此提交,但它会从索引中取消所有暂存(但未提交)的更改.最初(第1步),您想说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它将对所跟踪文件进行所有更改.要跟踪新文件,请更明确地指定它们.
Jav*_*ino 15
我有一个类似的问题,但我的回购中有很多悬垂的斑点和树木,所以我最终用grep所有悬空斑点的输出过滤并打印匹配的那些.假设${UNIQUE_CODE}某些代码对于索引中的文件是唯一的,那么这应该为您提供您正在寻找的blob的哈希值:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5562 次 |
| 最近记录: |