如何撤消Git中最近的本地提交?

问题描述 投票:19745回答:78

我不小心将错误的文件提交给Git,但我还没有将提交推送到服务器。

如何从本地存储库中撤消这些提交?

git version-control git-commit undo
78个回答
21362
投票

Undo a commit and redo

$ git commit -m "Something terribly misguided"             # (1)
$ git reset HEAD~                                          # (2)
<< edit files as necessary >>                              # (3)
$ git add ...                                              # (4)
$ git commit -c ORIG_HEAD                                  # (5)
  1. 这是您要撤消的内容。
  2. 这会使您的工作树(磁盘上的文件状态)保持不变但撤消提交并保留您未提交的更改(因此它们将在git status中显示为“未提交的更改”,因此您需要添加他们在提交之前再次)。如果您只想在上一次提交中添加更多更改,或者更改提交消息1,则可以使用git reset --soft HEAD~,这类似于git reset HEAD~(其中HEAD~HEAD~1相同),但会暂时保留您现有的更改。
  3. 对工作树文件进行更正。
  4. git add您想要包含在新提交中的任何内容。
  5. 提交更改,重用旧的提交消息。 reset将旧头复制到.git/ORIG_HEAD;使用commit-c ORIG_HEAD将打开一个编辑器,该编辑器最初包含来自旧提交的日志消息,并允许您编辑它。如果您不需要编辑消息,可以使用-C选项。

但请注意,如果您已向索引添加任何新更改,则使用commit --amend会将它们添加到您之前的提交中。

如果代码已经推送到您的服务器并且您有权覆盖历史记录(rebase),那么:

git push origin master --force

你也可以看看这个答案:

How to move HEAD back to a previous location? (Detached head) & Undo commits

上面的答案将向您展示git reflog,它用于找出您希望恢复的SHA-1是什么。一旦找到要撤消的点,就可以使用上面解释的命令序列。


1但是,请注意,如果您在提交消息中犯了错误,则无需重置为先前的提交。更简单的选择是git reset(取消您之后所做的任何更改),然后是git commit --amend,它将打开预先填充了最后一次提交消息的默认提交消息编辑器。


434
投票

我想在我们的共享存储库中撤消最新的5次提交。我查找了想要回滚的修订版ID。然后我键入以下内容。

prompt> git reset --hard 5a7404742c85
HEAD is now at 5a74047 Added one more page to catalogue
prompt> git push origin master --force
Total 0 (delta 0), reused 0 (delta 0)
remote: bb/acl: neoneye is allowed. accepted payload.
To [email protected]:thecompany/prometheus.git
 + 09a6480...5a74047 master -> master (forced update)
prompt>

413
投票

我更喜欢使用git rebase -i来完成这项工作,因为在我可以选择提交的地方弹出一个很好的列表。它可能不像其他答案那样直接,但它感觉恰到好处。

选择要列出的提交数量,然后像这样调用(以登记最后三个)

git rebase -i HEAD~3

样品清单

pick aa28ba7 Sanity check for RtmpSrv port
pick c26c541 RtmpSrv version option
pick 58d6909 Better URL decoding support

然后Git将删除您删除的任何行的提交。


398
投票

如何修复以前的本地提交

使用git-gui(或类似的)来执行git commit --amend。从GUI中,您可以从提交中添加或删除单个文件。您还可以修改提交消息。

如何撤消先前的本地提交

只需将分支重置为上一个位置(例如,使用gitkgit rebase)。然后从保存的副本中重新应用更改。在本地存储库中进行垃圾收集之后,就像从未发生过意外提交一样。要在单个命令中执行所有操作,请使用git reset HEAD~1

警告:不小心使用git reset是让你的工作副本进入混乱状态的好方法。我建议Git新手尽可能避免这种情况。

如何撤消公共提交

执行reverse cherry pickgit-revert)撤消更改。

如果您还没有将其他更改添加到您的分支,您可以简单地做...

git revert --no-edit HEAD

然后将更新的分支推送到共享存储库。

提交历史记录将分别显示两个提交。


高级:更正公共存储库中的专用分支

This can be dangerous -- be sure you have a local copy of the branch to repush.

另请注意:如果其他人可能正在分支机构工作,您不希望这样做。

git push --delete (branch_name) ## remove public version of branch

在当地清理您的分支,然后重新抢购......

git push origin (branch_name)

在正常情况下,您可能不必担心您的私有分支提交历史是原始的。只需推送一个后续提交(参见上面的“如何撤消公共提交”),然后执行squash-merge隐藏历史记录。


319
投票

如果你犯了垃圾而没有推,

git reset --soft HEAD~1

HEAD~1是head之前提交的简写。或者,如果要重置为,则可以参考哈希的SHA-1。 --soft选项将删除提交,但它将保留所有已更改的文件“要提交的更改”,因为git status会将其设置为。

如果你想在工作树中删除对工作树中跟踪文件的任何更改,那么在头部之前使用“--hard”代替。

要么

如果你已经推了并且有人拉了,这通常是我的情况,你不能使用git reset。但是你可以做一个git revert,

git revert HEAD

这将创建一个新的提交,以反转意外提交引入的所有内容。


317
投票

如果要永久撤消它并且已经克隆了一些存储库

提交ID可以通过以下方式查看

git log 

然后你可以做 -

git reset --hard <commit_id>

git push origin <branch_name> -f

269
投票

SourceTree(GitHub的GUI)上,您可以右键单击提交并执行“反向提交”。这应该撤消您的更改。

在终端上:

您也可以使用:

git revert

要么:

git reset --soft HEAD^ # Use --soft if you want to keep your changes.
git reset --hard HEAD^ # Use --hard if you don't care about keeping your changes.

250
投票

一个命令:

git reset --soft 'HEAD^' 

它可以很好地撤消上一次本地提交!


241
投票

只需使用git重置它,执行以下命令:

git reset --soft HEAD~1

解释:git reset做了什么,它基本上是reset到你要回去的任何提交,然后如果你把它与--soft键组合,它会返回,但保留你的文件中的更改,所以你回来到了刚刚添加文件的阶段,HEAD是分支的负责人,如果你与~1结合(在这种情况下你也使用HEAD^),它将只返回一个你想要的提交...

我将在下面的图片中为您创建更多详细信息,包括在实际情况下可能发生的所有步骤并提交代码:

How to undo the last commits in Git?


223
投票

如何撤消上次Git提交?

要将所有内容恢复到上次提交之前的状态,我们需要在HEAD之前重置为提交。

  1. 如果您不想保留所做的更改: git reset --hard HEAD^
  2. 如果您想保留更改: git reset --soft HEAD^

现在检查你的git日志。它将显示我们的上一次提交已被删除。


180
投票

使用reflog查找正确的状态

git reflog

重置前的REFLOG

选择正确的reflog(在我的例子中为f3cb6e2)并输入

git reset --hard f3cb6e2

之后,repo HEAD将重置为HEADID LOGET RESET RESET

最后,reflog如下图所示

最终的REFLOG


10302
投票

如果您不知道它是如何工作的,撤消提交有点可怕。但是如果你理解的话,它实际上非常容易。

假设您有这个,其中C是您的HEAD,(F)是您的文件的状态。

   (F)
A-B-C
    ↑
  master

你想要提交C并且永远不会再看到它。你做这个:

git reset --hard HEAD~1

结果是:

 (F)
A-B
  ↑
master

现在B是HEAD。因为您使用了--hard,所以您的文件将重置为它们在提交B时的状态。

啊,但是假设提交C不是灾难,而是一点点关闭。您希望撤消提交,但在进行更好的提交之前,请保留更改以进行一些编辑。从这里开始,用C作为你的HEAD:

   (F)
A-B-C
    ↑
  master

你可以这样做,不用--hard

git reset HEAD~1

在这种情况下,结果是:

   (F)
A-B-C
  ↑
master

在这两种情况下,HEAD只是指向最新提交的指针。当你执行git reset HEAD~1时,你告诉Git将HEAD指针移回一次提交。但是(除非你使用--hard)你保留文件原样。所以现在git status显示你已经检查过C的变化。你没有丢失任何东西!

对于最轻的触摸,您甚至可以撤消您的提交,但保留您的文件和index

git reset --soft HEAD~1

这不仅会使您的文件单独存在,甚至会使您的索引单独存在。当你执行git status时,你会看到索引中的文件和以前一样。事实上,在这个命令之后,你可以做git commit并且你将重做你刚刚做的同样的提交。

还有一件事:假设你在第一个例子中销毁了一个提交,但后来发现你需要它呢?运气好,对吗?

不,还有办法让它回来。输入git reflog,你会看到你已经移动过的(部分)提交shas(即散列)的列表。找到你销毁的提交,并执行以下操作:

git checkout -b someNewBranchName shaYouDestroyed

你现在复活了这个提交。提交实际上并没有在Git中被摧毁大约90天,所以你通常可以回去拯救一个你不想甩掉的人。


173
投票

“将工作树重置为上次提交”

git reset --hard HEAD^ 

“从工作树中清除未知文件”

git clean    

看 - Git Quick Reference

注意:此命令将删除您之前的提交,因此请谨慎使用! git reset --hard更安全 -


156
投票

第一次运行:

git reflog

它将显示您在存储库中执行的所有可能操作,例如,提交,合并,拉取等。

然后做:

git reset --hard ActionIdFromRefLog

148
投票

撤消上次提交:

git reset --soft HEAD^git reset --soft HEAD~

这将撤消上次提交。

这里--soft意味着重置为分期。

HEAD~HEAD^意味着在HEAD之前提交。


将上次提交替换为新提交:

git commit --amend -m "message"

它将用新提交替换最后一次提交。


143
投票

其他方式:

签出要还原的分支,然后将本地工作副本重置回您希望成为远程服务器上最新版本的提交(之后的所有内容将再次发生)。为此,在SourceTree中我右键单击并选择“将BRANCHNAME重置为此提交”。

然后导航到存储库的本地目录并运行以下命令:

git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

这将删除本地存储库中当前提交之后的所有提交,但仅删除该一个分支。


134
投票

输入git log并找到最后一次提交哈希码,然后输入:

git reset <the previous co>

130
投票

在我的情况下,我不小心提交了一些我不想要的文件。所以我做了以下工作:

git reset --soft HEAD^
git rm --cached [files you do not need]
git add [files you need]
git commit -c ORIG_HEAD

使用gitk或git log --stat验证结果


121
投票

很简单,在命令行中运行:

git reset --soft HEAD~ 

119
投票

有很多方法可以做到:

Git命令撤消上次提交/先前提交:

警告:如果您不知道自己在做什么,请不要使用--hard。 --hard太危险了,它可能会删除你的文件。

在Git中恢复提交的基本命令是:

$ git reset --hard <COMMIT -ID>

要么

$ git reset --hard HEAD~<n>

COMMIT-ID:提交的ID

n:是您要还原的最后提交数

您可以获得提交ID,如下所示:

$ **git log --oneline**

d81d3f1 function to subtract two numbers

be20eb8 function to add two numbers

bedgfgg function to mulitply two numbers

其中d81d3f1和be20eb8是commit id。

现在让我们看一些案例:

假设您要还原最后一次提交'd81d3f1'。这有两个选择:

$ git reset --hard d81d3f1

要么

$ git reset --hard HEAD~1

假设您要还原提交'be20eb8':

$ git reset --hard be20eb8

有关更多详细信息,您可以参考并尝试其他一些命令,以便将头重置为指定状态:

$ git reset --help

117
投票

For a local commit

git reset --soft HEAD~1

或者,如果您不记得究竟在哪个提交中,您可以使用

git rm --cached <file>

For a pushed commit

从存储库历史记录中删除文件的正确方法是使用git filter-branch。那是,

git filter-branch --index-filter 'git rm --cached <file>' HEAD

但我建议您小心使用此命令。在git-filter-branch(1) Manual Page了解更多信息。


117
投票

主要有两种情况

你尚未推送提交

如果问题是您提交的额外文件(并且您不想要存储库中的那些文件),您可以使用git rm删除它们然后提交--amend

git rm <pathToFile>

您还可以使用-r删除整个目录,甚至可以与其他Bash命令结合使用

git rm -r <pathToDirectory>
git rm $(find -name '*.class')

删除文件后,您可以使用--amend选项进行提交

git commit --amend -C HEAD # the -C option is to use the same commit message

这将重写您最近的本地提交删除额外的文件,因此,这些文件永远不会在推送时发送,也将被GC从本地.git存储库中删除。

你已经推送了提交

您可以应用其他方案的相同解决方案,然后使用git push选项执行-f,但不推荐使用它,因为它会以不同的更改覆盖远程历史记录(它可能会弄乱您的存储库)。

相反,你必须在没有--amend的情况下进行提交(记住这个关于-amend`:该选项在最后一次提交时重写历史记录)。


1969
投票

这花了我一段时间才弄明白,所以也许这会帮助别人......

根据您是否已将提交公开(推送到远程存储库),有两种方法可以“撤消”上次提交:

如何撤消本地提交

假设我在本地提交,但现在想删除该提交。

git log
    commit 101: bad commit    # latest commit, this would be called 'HEAD'
    commit 100: good commit   # second to last commit, this is the one we want

要将所有内容恢复到最后一次提交之前的方式,我们需要在reset之前将HEAD提交到提交:

git reset --soft HEAD^     # use --soft if you want to keep your changes
git reset --hard HEAD^     # use --hard if you don't care about keeping the changes you made

现在git log将显示我们的最后一次提交已被删除。

如何撤消公共提交

如果您已将提交公开,则需要创建一个新的提交,该提交将“还原”您在先前提交(当前HEAD)中所做的更改。

git revert HEAD

您的更改现在将被还原并准备好您提交:

git commit -m 'restoring the file I removed by accident'
git log
    commit 102: restoring the file I removed by accident
    commit 101: removing a file we don't need
    commit 100: adding a file that we need

有关更多信息,请查看Git Basics - Undoing Things


117
投票

要重置为先前的修订,请永久删除所有未提交的更改:

git reset --hard HEAD~1

1687
投票

添加/删除文件以获得您想要的方式:

git rm classdir
git add sourcedir

然后修改提交:

git commit --amend

之前的错误提交将被编辑以反映新的索引状态 - 换句话说,它就像你从未犯过错误一样。

请注意,只有在尚未推送的情况下才应执行此操作。如果你已推,那么你只需要正常提交修复。


957
投票
git rm yourfiles/*.class
git commit -a -m "deleted all class files in folder 'yourfiles'"

要么

git reset --hard HEAD~1

警告:上述命令将永久删除您要提交的.java文件(以及任何其他文件)的修改。

hard resetHEAD-1会在您错误提交之前将您的工作副本设置为提交状态。


726
投票

要更改上次提交

替换索引中的文件:

git rm --cached *.class
git add *.java

然后,如果它是一个私有分支,修改提交:

git commit --amend

或者,如果它是共享分支,则进行新的提交:

git commit -m 'Replace .class files with .java files'

(要更改先前的提交,请使用真棒interactive rebase


ProTip™:将*.class添加到gitignore以再次阻止这种情况发生。


要还原提交

如果您需要更改上次提交,则修改提交是理想的解决方案,但更通用的解决方案是reset

您可以将git重置为任何提交:

git reset @~N

其中NHEAD之前的提交数量,@~重置为之前的提交。

因此,您可以使用以下命令而不是修改提交:

git reset @~
git add *.java
git commit -m "Add .java files"

查看git help reset,特别是关于--soft --mixed--hard的部分,以便更好地理解它的作用。

引用日志

如果你陷入困境,你总是可以使用reflog来查找丢弃的提交:

$ git reset @~
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~
2c52489 HEAD@{1}: commit: added some .class files
$ git reset 2c52489
... and you're back where you started


614
投票

使用git revert <commit-id>

要获取提交ID,只需使用git log


495
投票

如果您计划完全撤消本地提交,无论您在提交时做了什么更改,如果您对此没有任何担心,只需执行以下命令即可。

git reset --hard HEAD^1

(此命令将忽略您的整个提交,您的更改将完全从本地工作树中丢失)。如果要撤消提交,但希望在暂存区域中进行更改(在提交之前,就像在git add之后),请执行以下命令。

git reset --soft HEAD^1

现在,您提交的文件将进入暂存区域。假设您想要更新文件,因为您需要编辑一些错误的内容,请执行以下命令

git reset HEAD

现在提交的文件从分阶段区域进入未分区区域。现在文件已经可以编辑了,所以无论你改变什么,你都要编辑并添加它并进行新的/新的提交。

More


467
投票

如果安装了Git Extras,则可以运行git undo来撤消最新的提交。 git undo 3将取消最后3次提交。

© www.soinside.com 2019 - 2024. All rights reserved.