使用暂存区中未提交的文件撤消 git reset --hard [英] Undo git reset --hard with uncommitted files in the staging area

查看:38
本文介绍了使用暂存区中未提交的文件撤消 git reset --hard的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力恢复我的工作.我愚蠢地做了 git reset --hard,但在此之前我只做了 get add . 而没有做 git commit.请帮忙!这是我的日志:

I am trying to recover my work. I stupidly did git reset --hard, but before that I've done only get add . and didn't do git commit. Please help! Here is my log:

MacBookPro:api user$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)

#   modified:   .gitignore
...


MacBookPro:api user$ git reset --hard
HEAD is now at ff546fa added new strucuture for api

在这种情况下是否可以撤消git reset --hard?

Is it possible to undo git reset --hard in this situation?

推荐答案

您应该能够恢复添加到索引中的任何文件(例如,在您的情况下,使用 git add .) 虽然它可能有点工作.为了将文件添加到索引中,git 将其添加到对象数据库中,这意味着只要垃圾收集尚未发生,它就可以恢复.中给出了如何执行此操作的示例Jakub Narębski 的回答在这里:

You should be able to recover any files back that you added to the index (e.g, as in your situation, with git add .) although it might be a bit of work. In order to add a file to the index, git adds it to the object database, which means it can be recovered so long as garbage collection hasn't happened yet. There's an example of how to do this given in Jakub Narębski's answer here:

但是,我在测试存储库中尝试了这一点,但有几个问题 - --cached 应该是 --cache,我发现它实际上并没有创建 .git/lost-found 目录.但是,以下步骤对我有用:

However, I tried that out on a test repository, and there were a couple of problems - --cached should be --cache, and I found that it didn't actually create the .git/lost-found directory. However, the following steps worked for me:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")

这应该输出对象数据库中任何引用、索引或通过引用日志都无法访问的所有对象.输出将如下所示:

That should output all objects in the object database that aren't reachable by any ref, in the index, or via the reflog. The output will look something like this:

unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03

...对于这些斑点中的每一个,您可以这样做:

... and for each of those blobs, you can do:

git show 907b308

输出文件内容.

更新以响应sehe在下面的评论:

Update in response to sehe's comment below:

如果您发现在该命令的输出中列出了许多提交和树,您可能希望从输出中删除未引用提交引用的任何对象.(通常,您无论如何都可以通过 reflog 返回这些提交 - 我们只对已添加到索引但永远无法通过提交找到的对象感兴趣.)

If you find that you have many commits and trees listed in the output from that command, you may want to remove from the output any objects which are referenced from unreferenced commits. (Typically you can get back to these commits via the reflog anyway - we're just interested in objects that have been added to the index but can never be found via a commit.)

首先保存命令的输出,用:

First, save the output of the command, with:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all

现在可以通过以下方式找到那些无法访问的提交的对象名称:

Now the object names of those unreachable commits can be found with:

egrep commit all | cut -d ' ' -f 3

因此,您可以仅找到已添加到索引但未在任何时候提交的树和对象,使用:

So you can find just the trees and objects that have been added to the index, but not committed at any point, with:

git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") 
  $(egrep commit all | cut -d ' ' -f 3)

这极大地减少了您必须考虑的对象数量.

That enormously cuts down the number of objects you'll have to consider.

更新:菲利普·奥克利在下面提出了另一种减少要考虑的对象,也就是只考虑 .git/objects 下最近修改的文件.您可以通过以下方式找到这些:

Update: Philip Oakley below suggests another way of cutting down the number of objects to consider, which is to just consider the most recently modified files under .git/objects. You can find these with:

find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p
' | sort

(我发现 find 调用 here.)该列表的结尾可能如下所示:

(I found that find invocation here.) The end of that list might look like:

2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a

在这种情况下,您可以使用以下命令查看这些对象:

In which case you can see those objects with:

git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a

(注意必须去掉路径末尾的/才能得到对象名.)

(Note that you have to remove the / at the end of the path to get the object name.)

这篇关于使用暂存区中未提交的文件撤消 git reset --hard的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆