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

git reset --hard HEAD~1

当前回答

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

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

希望这对某人有所帮助。

其他回答

您要做的是指定要还原到的提交的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重置时,它被放回原位。

如果Git尚未垃圾收集,则可以恢复它。

使用fsck获取悬空提交的概述:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

使用rebase恢复悬空提交:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

我知道这是一条古老的线索。。。但随着许多人在寻找如何在Git中撤销这些东西,我仍然认为在这里继续提供提示可能是一个好主意。

当您在gitgui中执行“gitadd”或将任何内容从左上角移动到左下角时,文件的内容存储在一个blob中,文件内容可以从该blob中恢复。

因此,即使文件未提交但必须已添加,也可以恢复该文件。

git init  
echo hello >> test.txt  
git add test.txt  

现在创建了blob,但它被索引引用,因此在重置之前,它不会与git fsck一起列出。所以我们重置。。。

git reset --hard  
git fsck  

您将得到一个悬空blob ce013625030ba8dba906f756967f9e9ca394464a

git show ce01362  

将向您返回文件内容“hello”

为了查找未引用的提交,我在某处找到了一个提示。

gitk --all $(git log -g --pretty=format:%h)  

我把它作为gitgui中的工具,它非常方便。

在大多数情况下,是的。

根据运行命令时存储库的状态,git reset-hard的效果可能从微不足道到撤消,甚至根本不可能。

下面我列出了一系列不同的可能情况,以及如何从中恢复。

我的所有更改都已提交,但现在提交都已取消!

这种情况通常发生在使用参数运行git-reset时,如git-reset--hardHEAD~。别担心,这很容易恢复!

如果您刚刚运行了git reset,并且此后没有做任何其他操作,那么您可以回到使用这一行程序的位置:

git reset --hard @{1}

这将重置当前分支,无论它在上次修改之前处于什么状态(在您的情况下,对分支的最近修改将是您尝试撤消的硬重置)。

但是,如果在重置之后对分支进行了其他修改,则上面的一行代码将不起作用。相反,您应该运行gitreflog<branchname>来查看最近对分支所做的所有更改(包括重置)的列表。该列表将如下所示:

7c169bd master@{0}: reset: moving to HEAD~
3ae5027 master@{1}: commit: Changed file2
7c169bd master@{2}: commit: Some change
5eb37ca master@{3}: commit (initial): Initial commit

在此列表中查找要“撤消”的操作。在上面的示例中,它将是第一行,即“重置:移动到HEAD~”。然后在该操作之前(下面)复制提交的表示。在我们的例子中,这将是master@{1}(或3ae5027,它们都表示相同的提交),并运行git-reset--hard<commit>将当前分支重置为该提交。

我用gitadd进行了更改,但从未提交。现在,我的改变消失了!

这有点难以恢复。git确实有您添加的文件的副本,但由于这些副本从未绑定到任何特定的提交,因此无法一次恢复所有更改。相反,您必须在git的数据库中找到各个文件并手动恢复它们。您可以使用git fsck执行此操作。

有关此操作的详细信息,请参阅Undo git reset-hard with subcommitted files in the staging area。

我对工作目录中的文件进行了更改,这些更改从未使用gitadd进行过,也从未提交过。现在,我的改变消失了!

噢。我不想告诉你这些,但你可能运气不好。git不存储未添加或提交的更改,根据git reset文档:

--硬的,硬的重置索引和工作树。自<commit>以来,对工作树中跟踪文件的任何更改都将被丢弃。

您可能可以使用某种磁盘恢复实用程序或专业的数据恢复服务来恢复更改,但在这一点上,这可能会带来更多的麻烦。