关于恢复:如何恢复Git中丢失的存储?

关于恢复:如何恢复Git中丢失的存储?

How to recover a dropped stash in Git?

我经常使用git stashgit stash pop来保存和恢复我的工作树中的更改。昨天我在我的工作树上做了一些改变,我把它们藏起来,然后我对我的工作树做了更多的改变。我想回去回顾一下昨天隐藏的更改,但是git stash pop似乎删除了对相关提交的所有引用。

我知道如果我使用git stash,那么.git/refs/stash包含用于创建stash的提交的引用。和.git/logs/refs/stash包含整个stash。但这些参考文献都是在git stash pop之后。我知道提交仍在我的存储库的某个地方,但我不知道它是什么。

有没有一个简单的方法来恢复昨天的库存承诺参考?

请注意,今天这对我来说并不重要,因为我有每日备份,可以返回昨天的工作树来获取更改。我问是因为一定有更简单的方法!


一旦你知道你的隐藏的哈希提交下降,你可以把它的应用:

1
git stash apply $stash_hash

或者,你可以创建一个单独的分支,它是以

1
git branch recovered $stash_hash

是的,你可以在任何你想要的,所有正常的工具。当你做,只是吹走的分公司。

寻找在哈希

如果你想跟它的只有终端仍然是开放的,你将仍然有git stash pop哈希值通过屏幕上的印刷(谢谢,逼疯了)。

此外,你可以找到它在Unix或Linux,这是,Git Bash的Windows:

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

使用Windows PowerShell的...or:

1
git fsck --no-reflog | select-string 'dangling commit' | foreach { $bits = $_ -split ' '; echo $bits[2];}

这将显示您的所有邮件在您的图,这是尖的时间提交相关的任何分支或标签,每个从每个提交的提交包括隐藏的失落,你所创造的地方,将在这样的图。

easiest找到隐藏的方式提交到你想要到那可能是通gitk列表:

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

从国有企业...or答案emragins如果使用Windows PowerShell。

这将启动你的浏览器显示的每个库的单库所提交的,无论它是否或不可访问的。

你可以有这样的事情gitkgit log --graph --oneline --decorate替换如果你选择好的图上的图形用户界面(GUI)在单独的控制台应用程序。

现场提交到变更的提交信息,看这个表:

# 160 160 # &;&;& # 160 160;和#;在制品在线somebranch:一些老commithash提交留言

注意:只有在这个信息将提交表单("在制品"开始的。)如果你没有当你做git stash供应信息。


如果您没有关闭终端,只需查看git stash pop的输出,就可以得到丢失存储的对象ID。通常看起来是这样的:

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

(注意,git stash drop也产生相同的线。)

要把那东西拿回来,只需运行git branch tmp 2cae03e,你就可以得到它作为一个分支。要将此转换为隐藏,请运行:

1
2
git stash apply tmp
git stash

把它作为一个分支也可以让您自由地操作它;例如,挑选它或合并它。


这就要提到除了在接受的解决方案。它不是立即明显的第一时间我想我这个方法(也许它应该被隐藏,而是利用从哈希值,就用"储藏应用":

1
$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

当我是新来的蠢货,这不是我的,我是透明的,尝试不同的组合,使用`git apply"秀"、"补丁",等等。


到这一stashes列表仍然是在您的处置,但不可访问的任何更多。

1
git fsck --unreachable | grep commit | cut -d"" -f3 | xargs git log --merges --no-walk --grep=WIP

如果你把你的标题是隐藏的,在"半成品"-grep=WIPAT命令与结束的部分-grep=Tesselation你的消息,例如。

该命令是"半成品",因为它grepping默认是隐藏的消息是在提交表单WIP on mybranch: [previous-commit-hash] Message of the previous commit.


我只是说我是人工命令:find my隐藏的失落。

1
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 /对象的树,这是一locates型汇总提交的,然后每一个节目。从这一点看,这是个问题,只是通过寻找适当的承诺":一6a9bb2在制品在线工作"("工作"是我的店,是一个新619bb2提交)。

我注意到,如果我使用"储藏"的申请,而不是流行的"储藏",我也不会有这样的问题,"如果我用储藏保存的消息",然后提交,可能已被更容易找到。

更新:这与弥敦道的思想,成为短。

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

git fsck --unreachable | grep commit应该显示它的值列表,但回报可能是相当大的。如果它是git show 将提交显示你想要的。

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


如果你想restash隐藏的失落,你需要找到你丢失的隐藏第一个哈希。

亚里士多德的pagaltzis显示git fsck应该帮助你。

我用我的个人演唱会,我的每一个log-all别名Commit(承诺做一个更好的recoverable)视图的情况:

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

你可以更快的搜索,如果你的一只正在寻找"半成品"的消息。

你知道你一次你用你的隐藏的变化值添加到reflog旧藏。

1
git update-ref refs/stash ed6721d

你可能宁愿有一只-m相关消息

1
git update-ref -m"$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721d

和你甚至想用这一别名:

1
restash = !git update-ref -m $(git log -1 --pretty=format:'%s' $1) refs/stash $1

使用Gitk的Windows PowerShell等效项:

gitk --all $(git fsck --no-reflog | Select-String"(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })

可能有一种更有效的方法可以在一根管道中完成这项工作,但这确实可以完成这项工作。


我喜欢亚里士多德的方法,但不喜欢使用Gitk…因为我习惯于从命令行使用git。

相反,我接受了悬空提交,并将代码输出到diff文件中,以便在代码编辑器中查看。

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

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

然后就用

1
git stash apply ad38abbf76e26c803b27a6079348192d32f52219

在使用Git2.6.4的OSX中,我只是不小心运行了GitStash Drop,然后我通过走到下面的步骤找到了它。

如果你知道藏品的名称,那么使用:

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2

否则,您将通过以下方式从结果中手动找到ID:

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show

然后当你找到提交ID时,点击git stash apply提交ID

希望这能尽快帮助别人


为什么人们会问这个问题?因为他们还不知道或者不了解反射波。

这个问题的大多数答案给出了长命令和选项,几乎没有人会记得。所以,人们开始思考这个问题,复制粘贴他们认为他们需要的东西,然后马上就忘记了。

我建议每个有这个问题的人只检查reflog(git reflog),不要超过这个。一旦您看到了所有提交的列表,就有100种方法可以找到您要寻找的提交,并从中挑选它或创建一个分支。在这个过程中,您将了解到reflog以及各种基本git命令的有用选项。


我想向接受的解决方案中添加另一种很好的方法来完成所有的更改,当您没有可用的Gitk或没有用于输出的x时。

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

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

然后,您会得到一个接一个显示的哈希的所有差异。按"Q"进入下一个差异。


亚里士多德接受的答案将显示所有可达到的承诺,包括非藏状的承诺。过滤噪音:

1
2
3
4
git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3

这将只包括只有3个父提交(存储将有)的提交,其消息包括"WIP开启"。

请记住,如果您用一条消息(如git stash save"My newly created stash"保存了您的库存,这将覆盖默认的"WIP开启…"消息。

您可以显示关于每个提交的更多信息,例如显示提交消息,或将其传递给git stash show

1
2
3
4
5
6
7
8
git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3 | \
xargs -n1 -I '{}' bash -c"\
  git log -1 --format=medium --color=always '{}'; echo; \
  git stash show --color=always '{}'; echo; echo" | \
less -R

在一个简单的命令窗口(在我的例子中是Windows7)中,我无法得到任何在Windows上工作的答案。awkgrepSelect-string不被认为是命令。所以我尝试了另一种方法:

  • 第一次运行:git fsck --unreachable | findstr"commit"
  • 将输出复制到记事本
  • 查找用start cmd /k git show替换"无法到达的提交"

看起来像这样:

start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4
start cmd /k git show 44078733e1b36962571019126243782421fcd8ae
start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1
start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e

  • 另存为.bat文件并运行它
  • 脚本将打开一组命令窗口,显示每个提交
  • 如果你找到了你要找的那个,跑:git stash apply (your hash)

也许不是最好的解决办法,但对我很有效


通过在终端中写入此命令,可以列出所有无法到达的提交。-

1
git fsck --unreachable

检查不可访问的提交哈希-

1
git show hash

找到藏品后再申请-

1
git stash apply hash

通过以下步骤恢复:

  • 标识已删除的存储哈希代码:

    Gitk--全部$(Git fsck--无reflog awk'/dangling commit/打印$3')

  • 樱桃挑选藏品:

    Git Cherry Pick-M 1$stash_hash_代码

  • 解决冲突,如果使用:

    吉特混血儿

  • 另外,如果使用gerrit,那么提交消息可能会有问题。请在以下备选方案之前保存您的更改:

  • 使用硬重置到上一次提交,然后重新提交此更改。
  • 您还可以保存更改,重新设置和重新提交。

  • 我来这里是想知道如何把藏品拿回来,不管我签了什么。特别是,我藏了一些东西,然后检查了一个旧版本,然后弹出了它,但在那个早期的时间点,藏的是一个不可操作的,所以藏的消失了;我不能只是做git stash把它推回到堆栈上。这对我很有用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ 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步骤上应用。现在我要做的是:

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

    我无意中把Gitup应用程序中的藏匿物移除了。只需按ctrl+z撤消。

    也许这对某人有帮助;)


    推荐阅读

      linux删除整个命令?

      linux删除整个命令?,命令,文件夹,不了,名称,通用,系统,数据,文件,目录,格式,l

      linux如何命令删除?

      linux如何命令删除?,档案,系统,命令,文件,目录,通用,文件夹,终端,选项,参数,l

      删除路由命令linux?

      删除路由命令linux?,系统,信息,网络,地址,管理,环境,路由,命令,工作,基础,WIN

      linux中ls命令恢复?

      linux中ls命令恢复?,系统,工具,信息,工作,命令,文件,目录,一致,电脑,基础,lin

      linux命令删除当前行?

      linux命令删除当前行?,系统,位置,命令,文件夹,文件,标的,数据,环境,通用,不

      linux删除jog命令?

      linux删除jog命令?,工具,软件,连续,机器人,位置,中心,工作,平稳,人员,自动化

      linux删除服务的命令?

      linux删除服务的命令?,服务,系统,软件,平台,名称,管理,环境,产品,命令,文件,

      linux删除rm命令?

      linux删除rm命令?,系统,命令,文件夹,不了,通用,名称,环境,文件,目录,下面,lin

      linux恢复命令行设置?

      linux恢复命令行设置?,系统,工作,密码,信息,工具,地址,电脑,命令,情况,地方,

      linux系统删除的命令?

      linux系统删除的命令?,软件,系统,名称,工具,不了,命令,文件夹,电脑,通用,信

      linux删除命令文件夹?

      linux删除命令文件夹?,系统,数据,通用,文件夹,命令,文件,环境,百度,不了,名

      linux恢复数据库命令?

      linux恢复数据库命令?,工具,系统,软件,数据,盘中,密码,命令,备份,数据库,文

      linux删除本行命令?

      linux删除本行命令?,系统,本行,档案,命令,资料,商业,文件,终端,目录,文件名,L

      linux历史命令恢复?

      linux历史命令恢复?,工具,数字,信息,命令,文件,地址,地方,系统,路径,备份,lin

      linux删除第一行命令?

      linux删除第一行命令?,单位,系统,命令,标的,不了,数字,连续,名称,档案,文件,m

      linux历史命令恢复?

      linux历史命令恢复?,工具,数字,信息,命令,文件,地址,地方,系统,路径,备份,lin

      linux删除本行命令?

      linux删除本行命令?,系统,本行,档案,命令,资料,商业,文件,终端,目录,文件名,L

      linux删除命令文件夹?

      linux删除命令文件夹?,系统,数据,通用,文件夹,命令,文件,环境,百度,不了,名

      linux删除第一行命令?

      linux删除第一行命令?,单位,系统,命令,标的,不了,数字,连续,名称,档案,文件,m

      linux里删除区间命令?

      linux里删除区间命令?,系统,命令,情况,档案,不了,名称,目录,文件,文件夹,分