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

git reset --hard HEAD~1

当前回答

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

git reset --hard <sha1 of desired commit>

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

其他回答

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

git reset --hard <sha1 of desired commit>

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

在回答之前,让我们添加一些背景,解释一下这个HEAD是什么。

首先,什么是头部?

HEAD只是对当前分支上当前提交(最新)的引用。在任何给定时间只能有一个HEAD。(不包括git工作树)

HEAD的内容存储在.git/HEAD中,它包含当前提交的40字节SHA-1。


分离式封头

如果您不在最近一次提交中,这意味着HEAD指向历史上的先前提交,它称为分离的HEAD。

在命令行上,它看起来像-SHA-1而不是分支名称,因为HEAD没有指向当前分支的尖端


关于如何从分离的HEAD恢复的几个选项:


git校验

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

这将签出指向所需提交的新分支。此命令将签出到给定的提交。此时,您可以创建一个分支并从此开始工作。

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

数字刷新

您也可以始终使用reflog。git reflog将显示更新HEAD的任何更改,检查所需的reflog条目将将HEAD设置回该提交。

每次修改HEAD时,reflog中都会有一个新条目

git reflog
git checkout HEAD@{...}

这会让你回到你想要的承诺


git reset HEAD--hard<commit_id>

将你的头“移”回所需的位置。

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.

注:(自Git 2.7以来)您也可以使用git rebase--也可以不使用autostash。



git还原<sha-1>

“撤消”给定的提交或提交范围。重置命令将“撤消”给定提交中所做的任何更改。将提交带有撤销补丁的新提交,而原始提交也将保留在历史记录中。

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

此模式说明了哪个命令执行什么操作。正如您可以看到的那样,重置和签出修改HEAD。

帕特·诺茨是正确的。你可以在几天内收回承诺。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