是否可以撤消由以下命令引起的更改?如果是,怎么办?

git reset --hard HEAD~1

当前回答

如果你真的很幸运,就像我一样,你可以回到你的文本编辑器,点击“撤销”。

我知道这确实不是一个正确的答案,但它节省了我半天的工作,所以希望它能为其他人做同样的事情!

其他回答

您要做的是指定要还原到的提交的sha1

git reset --hard <sha1 of desired commit>

但不要等太久。。。几周后,git将最终看到提交未被引用,并删除所有blob。

帕特·诺茨是正确的。你可以在几天内收回承诺。git只会在大约一个月后收集垃圾,除非您明确告诉它删除更新的blob。

$ git init
Initialized empty Git repository in .git/

$ echo "testing reset" > file1
$ git add file1
$ git commit -m 'added file1'
Created initial commit 1a75c1d: added file1
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file1

$ echo "added new file" > file2
$ git add file2
$ git commit -m 'added file2'
Created commit f6e5064: added file2
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file2

$ git reset --hard HEAD^
HEAD is now at 1a75c1d... added file1

$ cat file2
cat: file2: No such file or directory

$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2

$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2

$ cat file2
added new file

您可以在示例中看到,由于硬重置,file2被删除,但当我通过reflog重置时,它被放回原位。

注意:此答案仅在使用IntelliJ等IDE时有效

我最近遇到了一个类似的问题,我既没有进行改变,也没有做出承诺。可以选择当地历史。我能够从IntelliJ的本地历史还原更改(参考)。

希望这对某人有所帮助。

如果您还没有对存储库进行垃圾收集(例如,使用git重新打包-d或git gc,但请注意垃圾收集也可以自动进行),那么您的提交仍然存在,只是无法通过HEAD访问。

您可以尝试通过查看git fsck的输出来查找提交。

较新版本的Git有一种叫做“reflog”的东西,它是对ref所做的所有更改的日志(与对存储库内容所做的更改相反)。因此,例如,每次您切换HEAD时(即每次执行git签出以切换分支时),都会被记录。当然,你的git重置也操纵了HEAD,所以它也被记录了下来。您可以以类似于访问存储库的旧状态的方式访问ref的旧状态,方法是使用@符号而不是~,如git-resetHEAD@{1}。

我花了一段时间才明白HEAD@{1}和HEAD~1之间的区别,所以这里有一个小解释:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

因此,HEAD~1表示“在HEAD当前指向的提交之前进行提交”,而HEAD@{1}表示“在其当前指向的位置之前进行HEAD指向的提交”。

这将很容易让您找到丢失的提交并恢复它。

数字刷新

在列表中找到提交sha,然后将其复制并粘贴到以下命令中:

git cherry pick<the sha>