我正在使用源代码树。我已经创建了多个更改的存储,并错误地删除了它。有没有办法找回它们?
9 回答
根据上面的答案,这是一个简单的序列:
打开终端窗口并 cd 进入存储库下的文件夹。然后:
git fsck | awk '{print $3}' > tmp.txt
cat tmp.txt | xargs git show > tmp2.txt
现在在编辑器中打开tmp2.txt,找到丢失的代码,然后在上面找到commit-id。然后应用代码:
git stash apply <commit id>
rm tmp.txt tmp2.txt
这救了我的命!我真的很感谢所有回答这个问题的人。我感谢 git 创建者Linus Torvalds将已删除的内容保存在 git 数据库中。天才!!
编辑 2021:请注意,Windows 用户可以使用Git Bash执行相同的操作。
存储在内部保存为从存储列表引用的合并提交。
git fsck
可以找到悬空物体。它不仅会找到您已删除的存储,还可能会找到其他东西......所以您会想要寻找看起来可能是您的存储的提交(git show <ID>
以显示有关对象的相关信息并确定它是否是那个您正在寻找)。
一旦你有了它,你需要做的就是将它重新插入到存储列表中。该列表存储在.git/logs/refs/stash
其中,一行具有以下格式:
<ID of previous stash commit in list or 0000000000000000000000000000000000000000 if none> <ID of merge commit> Your Name <your@email.example> <UNIX timestamp> <time zone, e.g. +0000><TAB char><description of stash>
这是一个工作示例:
16b9a2d400dafe7ea25592029e3e5582d025c7d8 5def7605dfe625e8b3a3152fe52a87cc36694b6a Jan Krüger <email.censored@invalid> 1374227992 +0200 WIP on master: 0dbd812 Update draft release notes to 1.8.4
只需为要重新插入的 stash 合成一行(名称/邮件/时间戳/描述不必准确),您应该能够再次正常使用它。
狩猎愉快!
与之前的答案状态一样,您可以使用git fsck
列出未被任何包含已删除存储的对象引用的对象。但是,可以git show
用来过滤该对象列表以仅显示以下内容:
git fsck 2> /dev/null |
awk '/commit/{print $3}' |
git show --stdin --merges --grep '^WIP on'
如果您知道存储的创建时间,您还可以
--since '2 days ago'
在最后一行添加一个参数以进一步限制输出。希望这会将列表缩减到可管理的大小。
一旦你找到了正确的存储,记下它的提交 ID,你可以使用
git stash apply COMMITID
它来应用它,就好像它没有被删除一样。
在存储时使用注释可能会有所帮助,使用:
git stash save "comment"
使用以下方法为我节省了一些查找已删除存储的麻烦:
git fsck --lost-found
ls -1 .git/lost-found/commit/ | xargs -n 1 git log -n 1 --pretty=oneline
git stash apply [tag]
正如上面的 Jan Krüger 所说,git fsck
这是要走的路。但是,如果您发现自己(无论出于何种原因)无法成功合成 stash 文件中的一行并使该 stash 出现在可用列表中,您可以git stash apply <guid>
直接使用,而无需添加该行。这将立即将文件更改应用(而不是提交)到您当前的分支。
另一种解决方案是:
git fsck 2>&1 | awk '/dangling commit/{print $3 "^!"}' | xargs git log
查找作者和提交信息(日期、哈希、作者等)
git stash store <hash-id-of-specific-commit>
for i in $(git fsck 2>|/dev/null | grep commit | cut -d' ' -f3); do git --no-pager log -1 $i; echo "-------------------------"; done | less
然后找到提交 id#。
做
git stash apply {commit#}