如何撤消git reset --hard HEAD〜1?

时间:2020-03-05 18:38:30  来源:igfitidea点击:

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

git reset --hard HEAD~1

解决方案

回答

我们要做的是指定要还原到的提交的sha1. 我们可以通过检查reflog(git reflog)来获取sha1,然后执行

git reset --hard <所需提交的sha1>

但是不要等待太久...几周后git最终会将该提交视为未引用并删除所有blob。

回答

Pat Notz是正确的。只要几天之内就可以收回承诺。 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 repack -d或者git gc,但请注意垃圾回收也可以自动进行),那么提交仍然存在吗?它只是无法通过HEAD到达。

我们可以通过查看git fsck --lost-found的输出来尝试查找提交。

较新版本的Git具有称为" reflog"的内容,它是对ref所做的所有更改(与对存储库内容所做的更改相反)的日志。因此,例如,每次切换HEAD(即每次执行git checkout切换分支)时,都会记录该日志。而且,当然,git reset也操纵了HEAD,因此也记录了它。我们可以通过使用@而不是来访问引用的较早状态,就像访问存储库的较早状态一样,例如git reset HEAD @ {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指向当前指向的提交之前指向的提交。 "。

这样可以轻松地找到丢失的提交并进行恢复。