我该如何从本地仓库撤销这些提交?
要将内容重置为之前的版本,并永久删除所有未提交的更改:
git reset --hard HEAD~1
--soft
选项可以将您的更改保留为“未提交更改”,使用 --hard
选项可以完全删除提交并还原到前一个状态。请记住,仅对尚未推送的更改执行此类操作。 - Yunus Nedim Mehelgit reset --hard
完全丢弃,就像你所说的那样。 - cr7pt0gr4ph7git
都会将其内容存储在对象数据库中。只有在执行垃圾回收时才会删除存储的内容。因此,在执行 git reset --hard
时,可以恢复最后一个已暂存但当前未暂存的文件版本(有关更多信息,请参见上面链接的帖子)。 - cr7pt0gr4ph7撤销一个提交并丢弃任何未提交的更改
git reset --hard HEAD~1
撤销提交,但保留您的更改
git reset HEAD~1
保留您的文件,并自动将所有更改重新加入暂存区
git reset --soft HEAD~1
恢复您删除的提交
git reflog # 查找提交哈希值
sh
也是一种东西... - mirekphd假设我们有一个名为code.txt的文件。我们对它进行了一些更改并提交了这些更改。现在我们有三种方法可以撤销此次提交,但首先您需要知道什么是暂存文件...
一个暂存文件是指准备提交的文件,如果您运行 git status
命令,该文件将以绿色显示;如果未暂存以提交,则将以红色显示:
这意味着如果您提交更改,则对此文件进行的更改不会被保存。您可以使用 git add code.txt
将此文件添加到暂存区中,然后提交更改:
撤销上一次提交:
通常情况下,您希望撤消(commit)一个提交,是因为您犯了一个错误并且想要修复它 - 这本质上就是提问者(OP)在问问题时所做的事情。实际上,您实际上想要重做(commit)一个提交。
这里大多数答案都集中在命令行上。虽然当你熟悉 Git 后,命令行是使用 Git 的最佳方式,但对于那些来自其他版本控制系统的人来说,它可能有点陌生。
以下是使用 GUI 完成此操作的方法。如果您已安装 Git,则已经拥有完成这些说明所需的所有内容。
注意: 我假设您在推送(push)之前意识到提交(commit)错误。 如果您不知道推送是什么意思,那么您可能还没有推送。 请继续遵循说明。 如果您已经推送了有问题的提交(commit),则最不冒险的方法就是跟随有问题的提交(commit)进行修复,就像在不允许修改历史记录的版本控制系统中一样。
话虽如此,以下是使用 GUI 修复最近一个错误提交(commit)的方法:
git gui
启动 GUI。git reset HEAD~1 --mixed
您可以使用:
git reset HEAD@{1}
这条指令将在不使用Git日志的情况下删除您的错误提交。
撤销最后一次提交
有许多情况下,你可能真的想要撤销你在代码中进行的最后一次提交,例如因为你想要对其进行大量重构,甚至将其完全丢弃!
在这些情况下,“reset”命令是你最好的朋友:
$ git reset --soft HEAD~1
上述命令(reset)将把您当前的HEAD分支回到指定的修订版本。在上面的示例中,我们想返回到当前修订版本之前的版本 - 有效地撤销了我们最后一次提交。
请注意--soft
标志:这可以确保撤消的修订更改被保留。运行命令后,您将在工作副本中找到这些更改作为未提交的本地修改。
如果您不想保留这些更改,只需使用--hard
标志。请确保只有在确定不再需要这些更改时才执行此操作。
$ git reset --hard HEAD~1
撤销最后一次提交:
git reset --soft HEAD~
或者撤销上上次提交的更改:
git reset --soft HEAD~2
或撤销任何以前的提交:
git reset --soft <commitID>
(您可以使用git reflog
获取提交ID)
当您撤消先前的提交时,请记得使用以下命令清理工作区:
git clean
有关详细信息,请参阅文档:git-reset
在回答之前,让我们先解释一下什么是HEAD
。
首先,什么是HEAD?
HEAD
简单来说是当前分支上最新的提交(commit)的引用。
任何时候只能有一个HEAD
。(不包括git worktree
)
HEAD
的内容存储在.git/HEAD
中,其中包含当前提交的40个字节SHA-1值。
分离头指针
如果您不在最新的提交上 - 意味着 HEAD
指向历史记录中的先前提交,那么它被称为分离头指针
。
在命令行中,它看起来像这样- SHA-1代替分支名称,因为HEAD
没有指向当前分支的末端
git checkout
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>
git reflog
您总是可以使用reflog
。
git reflog
会显示更新HEAD
的任何更改,并检出所需的reflog条目将HEAD
设置回此提交。
每次修改HEAD时,都会在reflog
中创建一个新条目
git reflog
git checkout HEAD@{...}
这将使您返回到所需的提交
git reset --hard <commit_id>
将您的 HEAD 移回到所需的提交。
# 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 rebase --no-autostash
。git revert <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>
reset && checkout
修改了 HEAD
。
git reflog
已经接近你所描述的内容,但它给用户更多的控制权来确定需要(撤销)做的事情。但是请注意,“撤销”在各个地方的工作方式不同,人们会期望这个功能实现许多不同的事情。撤销上一个提交?撤销上一个操作?如果最后一个操作是推送,如何撤销,(重置并推送)还是(撤销并推送)? - Romain Valeri