git - Recover删除, 存储在Git

  显示原文与译文双语对照的内容

我经常使用 git stashgit stash pop 来保存和恢复工作树中的更改。 昨天,我在我的工作树,我有临时存储的和爆开,然后我进行了一些更改多个修改我的工作树。 我想返回并查看临时存储的关联,但是看来 git stash pop 来移除对昨日的更改提交。

然后我知道,如果我使用 git stash .git/refs/stash 包含该引用的提交用于创建隐匿处。 .git/logs/refs/stash 在整个仓库里都有 。 但这些引用在 git stash pop 之后消失了。 我知道提交仍然在我的仓库中,但我不知道它是什么。

是否有一个简单的方法来恢复昨天提交的提交引用?

注意,这个不重要对我来说,直到今天我有每天的备份并且可以回到工作昨日的树让我的更改。 我在问,因为必须有更简单的方法 !

时间:

在屏幕上里面跳出来如果只有它并由打出最终仍处于打开状态,则将还留着哈希值

否则,你可以使用以下方法找到它:


git fsck --no-reflog | awk '/dangling commit/{print $3}'

在那个graph,这会显示所有引用的提交你的提交在五角星形的图就无法得到来自任何分支或者标记- - 每一次失败的提交,包括每个藏匿提交你曾经创建时,将被纵横分布

找到你想要的存储提交的最简单方法可能是将该列表传递给 gitk:


gitk --all $( git fsck --no-reflog | awk '/dangling commit/{print $3}' )

随后将启动一个对版本库的浏览显示你每个单一提交在存储库中曾经,无论它是不是可以到达的。

你可以用类似于 git log --graph --oneline --decorate 如果你喜欢在控制台上使用一个独立的GUI应用。

要查找stash提交提交 commits,请查找这里表单的提交消息:

WIP在 somebranch : commithash一些旧的提交消息

一旦知道了所需提交的哈希值,就可以将它的应用为存储:

git stash apply $stash_hash

或者你可以使用 gitk 中的上下文菜单为你感兴趣的任何不可达提交创建分支。 之后,你可以用所有普通工具来做你想做的。 当你完成后,只需把那些分支重新打开。

如果你没有关闭终端,只需查看 git stash pop的输出,就可以得到被丢弃存储的对象标识。 它通常如下所示:


$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)

( 注意,git stash drop 也产生同样的行。)

要想找回那个仓库,只需运行 git branch tmp 2cae03e 你将把它作为一个分支。 要将它的转换为存储,请运行:


git stash apply tmp
git stash

使它成为分支也允许你自由地操作它;例如将它cherry-pick或者合并它。

只是想提一下这个被接受的解决方案。 我第一次尝试这个方法( 也许应该是) 时并不是很明显,但是要应用哈希值,只需使用"git存储应用":


$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

当我刚接触git时,这对我来说不清楚,我正在尝试"git显示","git应用","修补"等不同的组合。

我刚构建了一个命令,帮助我找到丢失的存储提交:


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/对象树中的所有对象,查找类型为commit的对象,然后显示每个对象的摘要。 从这一点来看,这只是一个查找提交的问题,寻找合适的"wip on: 6 a9bb2"("工作"是我的分支,619 bb2是最近的提交) 。

我注意到,如果我使用"git存储应用"而不是"git存储 pop",就不会有这个问题,如果我使用"git存储保存消息",那么提交可能会更容易找到。

更新:使用nathan的思想,这将变得更短:


for ref in `git fsck --unreachable | grep commit | cut -d' ' -f3`; do git show --summary $ref; done | less

git fsck --unreachable | grep commit 应该显示 sha1,尽管它返回的列表可能很大。 git show <sha1> 将显示是否为你想要的提交。

git cherry-pick -m 1 <sha1> 将提交合并到当前分支。

如果你想要restash丢失的存储,你需要先找到丢失的存储的散列。

就像亚里士多德Pagaltzis建议的那样,git fsck 应该能帮助你。

我个人使用我的log-all 别名,它向我展示了每个提交( 可以恢复的提交) 对情况有更好的看法:


git log --graph --decorate --pretty=oneline --abbrev-commit --all $(git fsck --no-reflogs | grep commit | cut -d -f3)

如果只查找"wip在"消息,你可以进行更快速的搜索。

一旦你知道了 sha1,你就可以简单地更改你的储藏reflog来添加旧的存储:


git update-ref refs/stash ed6721d

你可能希望有一个相关的消息,这样 -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

我喜欢亚里士多德的方法,但不喜欢使用 gitk 。 我习惯使用 命令行 中的GIT 。

相反,我采取了悬空提交,并将代码输出到一个DIFF文件,以便在我的代码编辑器中进行评审。


git show $( git fsck --no-reflog | awk '/dangling commit/{print $3}' )> ~/stash_recovery.diff

现在你可以将生成的diff/txt文件( 在你的主文件夹中) 加载到你的txt编辑器中,并查看实际代码并得到。

然后使用


git stash apply ad38abbf76e26c803b27a6079348192d32f52219

我想向被接受的解决方案添加另一个好的方法来遍历所有的更改,当你没有gitk可用或者没有用于输出时。


git fsck --no-reflog | awk '/dangling commit/{print $3}'> tmp_commits

for h in `cat tmp_commits`; do git show $h | less; done

然后你就会得到那些哈希的所有差异。 按'q'键到达下一个差异。

什么是我来这里寻找如何真正获取。储藏后,无论什么我核对了。 stack,上的特别是,我有临时存储的东西,然后检出旧版本,那么poped将它的,但筹码在一个no-op在那个较早的时间点,所以隐匿处,扩展消失;我不能只做 git stash 它回来, 我这里可以工作:


$ git checkout somethingOld
$ git stash pop
...
nothing added to commit but untracked files present (use"git add" to track)
Dropped refs/stash@{0} (27f6bd8ba3c4a34f134e12fe69bf69c192f71179)
$ git checkout 27f6bd8ba3c
$ git reset HEAD^ # Make the working tree differ from the parent.
$ git stash # Put the stash back in the stack.
Saved working directory and index state WIP on (no branch): c2be516 Some message.
HEAD is now at c2be516 Some message.
$ git checkout somethingOld # Now we are back where we were.

回想起来,我应该使用 git stash apply 而不是 git stash pop 。 我在做一个 bisect,并有一个小补丁,我想在每个 bisect 步骤应用它。 现在我将执行以下操作:


$ git reset --hard; git bisect good; git stash apply
$ # Run tests
$ git reset --hard; git bisect bad; git stash apply
etc.

...