我经常使用git stash
和git stash pop
来保存和恢复工作树中的更改。 昨天,我在工作树中进行了一些隐藏和弹出的更改,然后对工作树进行了更多更改。 我想回顾一下昨天的隐藏更改,但是git stash pop
似乎删除了对关联提交的所有引用。
我知道,如果我使用git stash
则.git / refs / stash包含用于创建隐藏的提交的引用。 .git / logs / refs / stash包含整个存储。 但是这些引用在git stash pop
之后消失了。 我知道提交仍在我的存储库中的某个位置,但是我不知道它是什么。
有没有简单的方法来恢复昨天的隐藏提交参考?
请注意,这对我今天并不重要,因为我每天都有备份,可以回到昨天的工作树中进行更改。 我问,因为必须有一个更简单的方法!
#1楼
当您没有gitk可用或没有X输出时,我想向接受的解决方案中添加另一种进行所有更改的好方法。
git fsck --no-reflog | awk '/dangling commit/ {print $3}' > tmp_commits
for h in `cat tmp_commits`; do git show $h | less; done
然后,您将获得这些散列的所有差异。 按“ q”进入下一个差异。
#2楼
我喜欢亚里斯多德的方法,但是不喜欢使用GITK ...,因为我习惯从命令行使用GIT。
相反,我悬挂了提交,并将代码输出到DIFF文件中,以便在代码编辑器中进行检查。
git show $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' ) > ~/stash_recovery.diff
现在,您可以将生成的diff / txt文件(位于主文件夹中)加载到txt编辑器中,并查看实际的代码和生成的SHA。
然后使用
git stash apply ad38abbf76e26c803b27a6079348192d32f52219
#3楼
我来这里寻找的是无论我已签出什么物品,如何真正地收回藏匿处。 特别是,我藏了一些东西,然后签出旧版本,然后弹出它,但是该存储在那个较早的时间点是空手道,因此该存储消失了; 我不能只是做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.
#4楼
通过使用以下步骤将其恢复:
确定已删除的隐藏哈希码:
gitk --all $(git fsck --no-reflog | awk'/ dangling commit / {print $ 3}')
樱桃挑藏:
git cherry-pick -m 1 $ stash_hash_code
解决冲突(如果有)使用:
git mergetool
另外,如果您使用的是gerrit,则提交消息可能会出现问题。 请保存您的更改,然后再执行下一个替代方案:
- 使用硬重置为上一次提交,然后重新提交此更改。
- 您也可以存储更改,重新设置基础并重新提交。
#5楼
等效于gitk的Windows PowerShell:
gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })
在一个管道中执行此操作可能是一种更有效的方法,但这可以完成工作。