撤消git重置 - 登台区域中没有任何不满的文件
我正在努力恢复我的工作。我愚蠢地做了git reset -hard
,但是在此之前,我只完成了获取添加。
,并且不做git commit
。请帮忙!这是我的日志:
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重置 - hard
?
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
Is it possible to undo git reset --hard
in this situation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
我刚刚进行了
git重置-Hard
,然后丢失了一个提交。但是我知道提交哈希,所以我能够做git cherry-pick commit_hash
来还原它。我在失去该提交的几分钟之内就这样做了,因此它可能对你们中的一些人有用。
I just did a
git reset --hard
and lost one commit. But I knew the commit hash, so I was able to dogit cherry-pick COMMIT_HASH
to restore it.I did this within a few minutes of losing the commit, so it may work for some of you.
感谢Mark Longair,我得到了我的东西!
首先,我将所有哈希保存到一个文件中:
接下来,我将它们全部放入列表中,然后将数据全部放入新文件中...您必须选择您的文件并将其重命名,然后重命名它们。需要...但是我只需要几个文件..希望这可以帮助某人...
Thanks to Mark Longair I got my stuff back!
First I saved all the hashes into a file:
next I put them all (removing the 'unreachable blob' thing) in a list and put the data all in new files...you have to pick your files and rename them again which you need...but I only needed a few files..hope this helps someone...
在这种情况下, @ajedi32的评论解决方案对我有用。
请注意,所有这些解决方案都依赖没有GIT GC,其中一些可能会导致一个解决方案,因此我会在尝试任何内容之前将您的.git目录的内容汇总,以便您有一个快照可以返回为您工作。
@Ajedi32's solution in the comments worked for me in exactly this situation.
Note that all these solutions rely on there being no git gc, and some of them might cause one, so I'd zip up the contents of your .git directory before trying anything so that you have a snapshot to go back to if one doesn't work for you.
遇到了同一问题,但没有将更改添加到索引中。因此,上面的所有命令都没有带给我所需的更改。
毕竟,这是一个幼稚的提示,但可能会像我一样拯救一个没有先考虑一下的人。
在绝望中,我试图在每个打开选项卡中按CTRL-Z(LightTable)中的CTRL-Z - 幸运的是,这在该选项卡中恢复了该文件,然后在
git reset-reset-Hard
之前恢复了其最新状态。 。Ran into the same issue, but had not added the changes to the index. So all commands above didn't bring me back the desired changes.
After all the above elaborate answers, this is a naive hint, but may be it'll save someone who didn't thought about it first, as I did.
In despair, I tried to press CTRL-Z in my editor (LightTable), once in every open tab — this luckily recovered the file in that tab, to its latest state before the
git reset --hard
.天哪,我拉了头发,直到遇到这个问题及其答案。我相信,只有将上面的两个评论拉在一起时,对问问题的正确和简洁的答案才可用,所以这里全部位于一个地方:
chilicuil提到,运行
git reflog
在那里识别您想回到
的提交哈希
除非您只丢失了一个提交,否则您应该运行
git重置 - hard&lt; hash-commit-you-want&gt;
for egit eclipse用户:我找不到一种方法用Egit进入Eclipse的步骤。关闭Eclipse,从终端窗口上方运行上面的命令,然后重新打开Eclipse对我来说很好。
Goodness, I pulled my hair until I ran into this question and its answers. I believe the correct and succinct answer to the question asked is only available if you pull two of the comments above together so here it is all in one place:
As mentioned by chilicuil, run
git reflog
to identify in there thecommit hash that you want to get back to
As mentioned by akimsko, you will likely NOT want to cherry pick
unless you only lost one commit, so you should then run
git reset --hard <hash-commit-you-want>
Note for egit Eclipse users: I couldn't find a way to do these steps within Eclipse with egit. Closing Eclipse, running the commands above from a terminal window, and then reopening Eclipse worked just fine for me.
如果您使用IDE编辑文件,则可能还可以将其自身的历史记录独立于git。在某些情况下,完全绕过git并使用IDE要简单得多。例如,Intellij Idea和Eclipse都具有这种自动化的本地版本控制,它们称为“本地历史”。在Intellij中,可以直接检索许多文件中的一批丢失的更改:在项目窗格中,您可以右键单击整个项目或目录树,然后选择“本地历史记录”子菜单中的显示历史记录。
git reset-- hard
应以“外部更改”(即从IDE外部触发)出现在列表中,您可以使用“还原”按钮或上下文菜单项将所有内容都恢复到状态就在发生外部变化之前。If you are editing your files with an IDE, it may also be keeping its own history independent of Git. In some circumstances it is much simpler to bypass Git entirely and use the IDE. For example, IntelliJ IDEA and Eclipse both have this kind of automated local version control, which they refer to as "local history". In IntelliJ it's straightforward to retrieve a whole batch of lost changes across many files: in the Project pane, you can right-click an entire project or directory tree and select Show History in the Local History submenu. The
git reset --hard
should appear in the list as an "external change" (i.e. triggered from outside the IDE), and you can use the revert button or context menu item to revert everything to the state right before that external change happened.对于那里的GIT专业人员来说,这可能是显而易见的,但是我想提出这一点,因为在我疯狂的搜索中,我没有看到这种情况。
我上演了一些文件,并进行了
git重置 - hard
,吓坏了一点,然后注意到我的状态显示了我所有的文件仍在上演,并且所有删除所有删除都没有上演。在这一点上,只要您不进行他们的删除,您就可以进行那些分阶段的更改。
之后,您只需要勇于努力进行
git重置 - hard
又一次,这将使您回到您上演的那些更改,现在刚刚承诺。同样,这对大多数人来说可能并不新鲜,但是我希望这对我有帮助,而且我没有发现任何暗示这一点,所以它可能会对其他人有所帮助。
This is probably obvious to the git professionals out there, but I wanted to put it up since in my frantic searching I didn't see this brought up.
I staged some files, and did a
git reset --hard
, freaked out a little, and then noticed that my status showed all my files still staged as well as all their deletions unstaged.At this point you can commit those staged changes, as long as you don't stage their deletions.
After this, you only have to work up the courage to do
git reset --hard
one more time, which will bring you back to those changes you had staged and now just committed.Again, this is probably nothing new to most, but I'm hoping that since it helped me and I didn't find anything suggesting this, it might help someone else.
如果您最近查看了
git diff
,那么还有另一种方法可以从这样的事件中恢复,即使您还没有上演更改:如果git git diff 仍在控制台缓冲区中,您可以滚动,将差异复制到文件中,然后使用
patch
工具将差异应用于树:patch -patch -p0&lt;文件
。这种方法为我节省了几次。If you've recently reviewed a
git diff
then there's another way to recover from incidents like this, even when you haven't staged the changes yet: if the output ofgit diff
is still in your console buffer, you can just scroll up, copy-paste the diff into a file and use thepatch
tool to apply the diff to your tree:patch -p0 < file
. This approach saved me a few times.但是,上述解决方案可能起作用,但是,有更简单的方法可以从中恢复过来
这不是通过
git
-s复杂的撤消。我猜最多git-resets发生在少数文件上,如果您已经使用了vim,则
可能是最耗时的解决方案。警告是你已经必须
使用
vim的
persistent-undo,您应该使用两种方式,因为它为您提供了消除无限数量更改的能力。
以下是:
在vim中按:键入命令
设置dudodir
。如果您有持续
,它将显示与类似的结果在您的
.vimrc
中启动undodir =〜/.vim_runtime/temp_dirs/dododir
。在您的回购中使用
git log
以查找最后的日期/时间提交
使用
dudodir
使用cd〜/.vim_runtime/temp_dirs/undodir
。在此目录中使用此命令来查找您拥有的所有文件
自上次提交以来改变了
寻找 。 -Newermt“ 2018-03-20 11:24:44” \! -newermt“ 2018-03-23” \(-type f
-regextype posix -extended -regex'。*'\)\ - not -path'*/env/*” - not -path -path
“*/。git/*”
在这里“ 2018-03-20 11:24:44”是上次提交的日期和时间。如果是
您进行
git重置的日期-Hard
是“ 2018-03-22”,然后使用“ 2018-03-22”,然后使用“ 2018-03-23”。这是因为发现的怪癖,
下边界是包容性的,上限是独家的。
https://unix.stac.stackexchange.com/a/a/70404/242983
您可以通过使用“ h之前”找到有关“较早”的更多详细信息。这里
早期20m
是指20分钟前返回文件状态,假设您在20分钟后进行了
git -reset
。重复一遍从
find
命令中删除的所有文件。我相信有人可以编写一个将这些内容结合在一起的脚本。
The above solutions may work, however, there are simpler ways to recover from
this instead of going through
git
-s complex undo. I would guess that mostgit-resets happen on a small number of files, and if you already use VIM, this
might be the most time-efficient solution. The caveat is that you already must
be using
ViM's
persistent-undo, which you should be using either way, becauseit provides you the ability to undo unlimited number of changes.
Here are the steps:
In vim press
:
and type the commandset undodir
. If you havepersistent
turned on in yourundo
.vimrc
, it will show a result similar toundodir=~/.vim_runtime/temp_dirs/undodir
.In your repo use
git log
to find out the last date/time you made the lastcommit
In your shell navigate to your
undodir
usingcd ~/.vim_runtime/temp_dirs/undodir
.In this directory use this command to find all the files that you have
changed since the last commit
find . -newermt "2018-03-20 11:24:44" \! -newermt "2018-03-23" \( -type f
-regextype posix-extended -regex '.*' \) \-not -path "*/env/*" -not -path
"*/.git/*"
Here "2018-03-20 11:24:44" is the date and time of the last commit. If the
date on which you did the
git reset --hard
is "2018-03-22", then use"2018-03-22", then use "2018-03-23". This is because of a quirk of find,
where the lower boundary is inclusive, and the upper bound is exclusive.
https://unix.stackexchange.com/a/70404/242983
Next go to each of the files open them up in vim, and do a "earlier 20m".
You can find more details about "earlier" by using "h earlier". Here
earlier 20m
mean go back to the state of the file 20 minutes back,assuming that you did the
git hard --reset
, 20 mins back. Repeat this overall the files that was spitted out from the
find
command. I am suresomebody can write a script that will combine these things.
我正在使用Intellij,并且能够简单地浏览每个文件并进行:
edit-&gt;从磁盘重新加载
幸运的是,我刚刚完成了
git状态
,然后才能消除工作更改,因此我确切地知道我必须重新加载的内容。I'm using IntelliJ and was able to simply go through each file and do:
Edit -> reload from disk
Luckily, I had just done a
git status
right before I wiped out my working changes, so I knew exactly what I had to reload.我无法使用git命令恢复文件。就我而言,这是一个CPP文件。我知道其中一个独特的字符串, this 帮助了。命令是:
搜索整个磁盘,但最终找到了丢失文件的内容。
I was not able to recover the file using git commands. In my case, it was a CPP file. I knew a unique string in it and this helped. The command is:
Searches the whole disk but in the end, it found the content of the lost file.
记住您的文件层次结构并使用Mark Longair进行Phil Oakley修改的技术会产生巨大的结果。
从本质上讲,如果您至少将文件添加到存储库中但不承诺,则可以通过使用
git show
进行交互恢复,检查日志并使用shell重定向来创建每个文件(记住您的感兴趣的路径) 。Remembering your file hierarchy and using the technique of Mark Longair with Phil Oakley modification yields dramatic results.
Essentially if you at least added the files to the repo but not committed it, you can restore by interactively using
git show
, inspect the log and use shell redirection to create each file (remembering your path of interest).使用Intellij Idea的本地历史功能
我也处于类似情况,但没有承诺的更改,并且没有添加到索引(git add。),我成功地 恢复了它。
如果您使用的是Intellij Idea,请按照以下步骤:
这将恢复您的未承诺的更改。
Recover your uncommitted changes using IntelliJ IDEA's local history feature
I was also in the similar situation but with uncommitted changes and also wasn't added to index (git add .), I successfully recovered it.
If you're using IntelliJ IDEA, please follow the below steps:
This will revert back your uncommitted changes.
您应该能够恢复添加到索引中的任何文件(例如,如您的情况,
git add。
),尽管可能有点工作。为了将文件添加到索引中,GIT将其添加到对象数据库中,这意味着只要垃圾收集尚未发生,就可以将其恢复。有一个示例,说明了在 jakubnarębski的答案在这里:但是,我在测试存储库上尝试了一下,并且有一些问题 -
- cached
应该是- cache ,我发现它实际上并未创建
.git/oftost-found
目录。但是,以下步骤对我有用:该步骤应在对象数据库中输出所有参考,索引中或通过reflog无法触及的对象。输出看起来像这样:
...对于每个斑点,您都可以做:
输出文件的内容。
输出太多?
响应 sehe 在下面的评论:
从该命令中列出的树中列出的树,您可能需要从未参考提交中引用的任何对象中删除任何对象。 (通常您可以通过反射仪回到这些提交 - 我们只是对已添加到索引但永远无法通过提交的对象感兴趣。)
首先,保存命令的输出,现在:
现在可以找到这些无法到达的提交的对象名称:
因此,您可以找到已添加到索引中但在任何时候添加到索引中的树和对象,并以:
大量缩小您所拥有的对象的数量考虑。
更新: philip oakley 下面建议您削减对象数量的另一种方法,以考虑考虑考虑考虑的对象数量,即仅在
.git/对象
下考虑最近修改的文件。您可以使用以下方式找到这些信息:(我发现
查找
invocation 在这里。)该列表的结尾可能看起来像:在这种情况下,您可以看到这些对象:(
请注意,您必须在路径末端删除
/
以获取对象名称。 )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: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: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:
... and for each of those blobs, you can do:
To output the contents of the file.
Too much output?
Update in response to sehe's comment below:
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:
Now the object names of those unreachable commits can be found with:
So you can find just the trees and objects that have been added to the index, but not committed at any point, with:
That enormously cuts down the number of objects you'll have to consider.
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:(I found that
find
invocation here.) The end of that list might look like:In which case you can see those objects with:
(Note that you have to remove the
/
at the end of the path to get the object name.)