题 如何在Git中恢复被删除的存储?
我经常使用 git stash
和 git stash pop
保存和恢复工作树中的更改。昨天我的工作树上有一些变化,我已经藏起来了,然后我对工作树做了更多修改。我想回去看看昨天发生的变化,但是 git stash pop
似乎删除了对关联提交的所有引用。
我知道,如果我使用 git stash
然后 .git / refs / stash包含 用于创建存储的提交的引用。和 .git / logs / refs / stash包含 整个藏匿处。但那些参考文献已经消失了 git stash pop
。我知道提交仍然在我的存储库中,但我不知道它是什么。
有没有一种简单的方法来恢复昨天的隐藏提交引用?
请注意,这对我来说并不重要,因为我每天都有备份,可以回到昨天的工作树来获取我的更改。我问,因为必须有一个更简单的方法!
1334
2017-09-18 01:59
起源
答案:
如果您刚刚弹出它并且终端仍然打开,您将会 仍然有打印的哈希值 git stash pop
在屏幕上 (谢谢,Dolda)。
否则,你可以在Linux和Unix上找到它:
git fsck --no-reflog | awk '/dangling commit/ {print $3}'
对于Windows:
git fsck --no-reflog | select-string 'dangling commit' | foreach { $bits = $_ -split ' '; echo $bits[2];}
这将向您显示提交图提示中的所有提交,这些提交不再从任何分支或标记引用 - 每个丢失的提交(包括您创建的每个存储提交)都将位于该图中的某个位置。
找到所需存储提交的最简单方法可能是将该列表传递给 gitk
:
gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )
这将启动显示您的存储库浏览器 存储库中的每一次提交都是如此,无论是否可达。
你可以替换 gitk
有类似的东西 git log --graph --oneline --decorate
如果您喜欢通过单独的GUI应用程序在控制台上使用漂亮的图形。
要查找存储提交,请查找此表单的提交消息:
WIP上 somebranch: commithash一些旧的提交消息
注意:如果您没有提供消息,则提交消息将仅采用此形式(以“WIP on”开头) git stash
。
一旦知道了所需提交的哈希值,就可以将其应用为存储:
git stash apply $ stash_hash
或者您可以使用上下文菜单 gitk
为您感兴趣的任何无法访问的提交创建分支。之后,您可以使用所有常规工具随意执行任何操作。当你完成后,再次吹走那些树枝。
2159
2017-09-18 11:38
如果您没有关闭终端,只需查看输出 git stash pop
并且你将拥有被删除的藏匿的对象ID。它通常看起来像这样:
$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)
(注意 git stash drop
也产生相同的线。)
为了获得那些藏匿,只需运行 git branch tmp 2cae03e
,你会把它作为一个分支。要将其转换为存储,请运行:
git stash apply tmp
git stash
将它作为分支也允许您自由地操作它;例如,樱桃挑选或合并它。
598
2017-10-21 03:13
只是想提到对已接受的解决方案的这一补充。我第一次尝试这种方法时并不是很明显(也许应该是这样),但是要从哈希值中应用存储,只需使用“git stash apply”:
$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219
当我刚开始使用git时,这对我来说并不清楚,我正在尝试“git show”,“git apply”,“patch”等的不同组合。
232
2018-03-03 20:28
我刚刚构建了一个命令,帮助我找到丢失的存储提交:
for ref in `find .git/objects | sed -e 's#.git/objects/##' | grep / | tr -d /`; do if [ `git cat-file -t $ref` = "commit" ]; then git show --summary $ref; fi; done | less
这将列出.git / objects树中的所有对象,找到类型为commit的对象,然后显示每个对象的摘要。从这一点来看,只需查看提交内容即可找到合适的“WIP on work:6a9bb2”(“work”是我的分支,619bb2是最近的提交)。
我注意到如果我使用“git stash apply”而不是“git stash pop”我就不会有这个问题,如果我使用“git stash save” 信息“那么提交可能更容易找到。
更新:根据内森的想法,这变得更短:
for ref in `git fsck --unreachable | grep commit | cut -d' ' -f3`; do git show --summary $ref; done | less
68
2017-09-18 02:10
要获取仍在存储库中但不再可访问的存储列表:
git fsck --unreachable | grep commit | cut -d" " -f3 | xargs git log --merges --no-walk --grep=WIP
如果您为藏匿处提供了标题,请将“WIP”替换为 -grep=WIP
在命令的末尾,包含部分信息,例如 -grep=Tesselation
。
该命令正在grepping“WIP”,因为存储的默认提交消息在表单中 WIP on mybranch: [previous-commit-hash] Message of the previous commit.
57
2018-05-04 06:42
git fsck --unreachable | grep commit
应该显示sha1,尽管它返回的列表可能非常大。 git show <sha1>
将显示它是否是您想要的提交。
git cherry-pick -m 1 <sha1>
将提交合并到当前分支。
36
2017-09-18 02:08
如果你想重建一个丢失的藏匿处,你需要先找到丢失的藏匿的哈希值。
正如亚里士多德帕加齐斯所说的那样 git fsck
应该帮助你。
我个人用我的 log-all
别名向我展示每次提交(可恢复的提交)以更好地了解情况:
git log --graph --decorate --pretty=oneline --abbrev-commit --all $(git fsck --no-reflogs | grep commit | cut -d' ' -f3)
如果您只查看“WIP on”消息,则可以进行更快速的搜索。
一旦你知道你的sha1,你只需更改你的存储reflog以添加旧的存储:
git update-ref refs/stash ed6721d
你可能更愿意有一个相关的消息,所以a -m
git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721d
你甚至想用它作为别名:
restash = !git update-ref -m $(git log -1 --pretty=format:'%s' $1) refs/stash $1
23
2018-06-23 14:20