如何撤消Git中的最后一个提交?
我意外地把错误的文件保存到了Git中 ,但是我还没有将提交提交到服务器。
我怎样才能撤销这些提交?
撤销提交并重做
$ 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)
- 这是你想要撤消的
- 这会使您的工作树(磁盘上的文件状态)保持不变,但会撤销提交并保留您未提交的更改(所以在
git status
它们将显示为“更改不提交进行提交”,您需要在提交之前再次添加它们)。 如果你只想添加更多的更改到上一个提交,或者更改提交消息1 ,你可以使用git reset --soft HEAD~
来代替,就像git reset HEAD~
git reset --soft HEAD~
,但是git reset --soft HEAD~
现有的更改。 - 更正工作树文件。
-
git add
任何你想包括在你的新提交。 - 提交更改,重新使用旧的提交消息。
reset
将旧的磁头复制到.git/ORIG_HEAD
;commit
-c ORIG_HEAD
将打开一个编辑器,它最初包含来自旧提交的日志消息,并允许您编辑它。 如果您不需要编辑消息,则可以使用-C
选项。
1但是请注意,如果您在提交消息中犯了错误,则不需要重置为较早的提交。 更容易的select是git reset
(以上所做的任何更改),然后git commit --amend
,这将打开您的默认提交消息编辑器预填充最后的提交消息。
但要小心,如果你已经对索引添加了新的改变,使用commit --amend
将把它们添加到你以前的提交中。
如果你不知道它是如何工作的,那么撤消一个提交是有点吓人的。 但是,如果你理解的话,这真的很容易。
说你有这个,C是你的头,(F)是你的文件的状态。
(F) ABC ↑ master
你想核实提交C,永远不会再看到它 。 你做这个:
git reset --hard HEAD~1
结果是:
(F) AB ↑ master
现在B是头。 因为你使用了--hard
,所以你的文件被重置为它们在提交B的状态。
啊,但是假设提交C不是一场灾难,而是一点点。 您希望撤销提交,但在做出更好的提交之前保留一些修改 。 从这里开始,用C作为你的头:
(F) ABC ↑ master
你可以做到这一点,离开了 – --hard
:
git reset HEAD~1
在这种情况下,结果是:
(F) ABC ↑ master
在这两种情况下,HEAD只是一个指向最新提交的指针。 当你做一个git reset HEAD~1
,你告诉Git把HEAD指针移回一个提交。 但是(除非你使用--hard
),你把文件保持原样。 所以,现在git status
显示你已经检查到C的变化。你还没有失去一个东西!
为了最轻松的触摸,你甚至可以撤消你的提交,但离开你的文件和你的索引 :
git reset --soft HEAD~1
这不仅使你的文件独立,它甚至离开你的索引 。 当你做git status
,你会看到相同的文件在索引像以前一样。 事实上,在这个命令之后,你可以做git commit
,你会重做刚才的同一个提交。
还有一件事情: 假设你像第一个例子那样销毁一个提交 , 但是最终发现你需要它呢? 运气不好,对不对?
不, 还是有办法把它弄回来。 inputgit reflog
,你会看到你已经移动过的(部分)commit shas列表。find你所销毁的提交,然后执行以下操作:
git checkout -b someNewBranchName shaYouDestroyed
你现在已经复活了那个提交。 在90天内,提交并没有在Git中真正被销毁,所以你通常可以回去拯救一个你并不想要的东西。
添加/删除文件,以您想要的方式获取内容:
git rm classdir git add sourcedir
然后修改提交:
git commit --amend
之前的错误提交将被编辑以反映新的索引状态 – 换句话说,就像您从来没有犯过错误。
请注意,如果您尚未推送,则只能执行此操作。 如果你推了,那么你只需要正常提交修复。
这花了我一段时间才弄清楚,所以也许这会帮助别人…
有两种方法可以“撤销”最后一次提交,具体取决于是否已经公开提交(推送到远程存储库):
如何撤消本地提交
比方说,我承诺本地,但现在要删除该提交。
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
将显示我们的最后提交已被删除。
如何撤消公共提交
如果你已经公开提交你的提交,你会想要创build一个新的提交,它将“恢复”你在之前的提交(当前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 dont need commit 100: adding a file that we need
有关更多信息,请查看Git基础知识 – 撤消事物
git rm yourfiles/*.class git commit -a -m "deleted all class files in folder 'yourfiles'"
要么
git reset --hard HEAD~1
警告:上述命令将永久删除您想要提交的.java
文件(和任何其他文件)的修改。
HEAD-1的硬重置会将您的工作副本设置为错误提交之前的提交状态。
改变最后的提交
replace索引中的文件:
git rm --cached *.class git add *.java
那么,如果它是一个私人分支, 修改提交:
git commit --amend
或者,如果它是共享分支,则进行新的提交:
git commit -m 'Replace .class files with .java files'
( 改变以前的提交 ,使用真棒交互式底座 )
ProTip™:将*.class
添加到gitignore以停止再次发生。
恢复提交
如果您需要更改上次提交,那么修改提交是理想的解决scheme,但更常用的解决scheme将被reset
。
你可以重置git到任何提交:
git reset @~N
其中N
是HEAD
之前的提交数量, @~
重置为以前的提交。
所以,而不是修改提交,你可以使用:
git reset @~ git add *.java git commit -m "Add .java files"
查看git help reset
,特别是关于--soft
--mixed
和--hard
的部分,以便更好地理解这个function。
引用日志
如果你搞砸了,你总是可以使用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
使用git revert commit-id
要获取提交ID,只需使用git log
如果您计划完全撤消本地提交,则无论您在提交时做了什么更改,如果您不担心这一点,只需执行以下命令即可。
git reset --hard HEAD^1
(这个命令会忽略你的整个提交,你的改变将会从你的本地工作树中完全丢失)。 如果你想撤销你的提交,但你希望你的更改在临时区(在提交之前就像git add
),然后执行以下命令。
git reset --soft HEAD^1
现在你提交的文件进入暂存区。 假设如果你想取消文件,因为你需要编辑一些错误的conent,然后执行以下命令
git reset HEAD
现在提交的文件从暂存区进入未分区。 现在文件已经准备好进行编辑了,所以无论你做什么改变,你都要编辑并添加它,并做出新的/新的提交。
更多
如果你安装了Git Extras ,你可以运行git undo
来撤销最新的提交。 git undo 3
将撤消最后3个提交。
我想撤消共享库中最新的5个提交。 我查了一下我想要回滚的修订版本ID。 然后我input以下内容。
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 git@bitbucket.org:thecompany/prometheus.git + 09a6480...5a74047 master -> master (forced update) prompt>
我更喜欢使用git rebase -i
这个工作,因为一个不错的列表popup来,我可以select提交来摆脱。 这可能不像其他一些答案那样直接,但它感觉正确 。
select你想要列出的提交数量,然后像这样调用(为了获得最后三个)
git rebase -i HEAD~3
示例列表
pick aa28ba7 Sanity check for RtmpSrv port pick c26c541 RtmpSrv version option pick 58d6909 Better URL decoding support
然后,git将删除您删除的任何行的提交。
如何修复以前的本地提交
使用git-gui(或类似的)来执行git commit --amend
。 在GUI中,您可以添加或删除提交中的单个文件。 您也可以修改提交消息。
如何撤销以前的本地提交
只需将您的分支重置到以前的位置(例如,使用gitk
或git rebase
)。 然后从保存的副本中重新应用您的更改。 在本地存储库中进行垃圾收集之后,它将会像不曾发生的不需要的提交一样。 要在单个命令中完成所有这些,请使用git reset HEAD~1
。
警告 字句 : 不小心使用git reset
是将工作副本置于混乱状态的好方法。 如果可以,我build议Git新手避免这种情况。
如何撤消公共提交
执行反向樱桃select ( git-revert )以撤消更改。
如果您还没有将其他更改拖到您的分支,您可以简单地做…
git revert --no-edit HEAD
然后将更新的分支推送到共享存储库。
如果你犯了垃圾但没有推,
git reset --soft HEAD~1
HEAD〜1是头部提交的缩写。 或者,如果你想重置,你可以参考散列的SHA-1 。 –soft选项将删除提交,但它会保留所有更改的文件“更改被提交”,因为git状态会把它。
如果你想摆脱工作树中跟踪文件的任何变化,因为在头部使用“ –hard ”之前提交。
要么
如果你已经推了,而且有人拉我的情况,你不能使用git reset 。 你可以做一个git还原 ,
git revert HEAD
这将创build一个新的提交,以反转意外提交引入的所有内容。
如果你想永久撤销它,并且你已经克隆了一些仓库
提交ID可以被看到
git log
那么你可以做 –
git reset --hard <commit_id> git push origin <branch_name> -f
在SourceTree (GUI for GitHub)上,您可以右键单击提交并执行“反向提交”。 这应该撤消你的改变。
在docker上:
您也可以使用:
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.
一个命令:
git reset --soft 'HEAD^'
它很好地撤消最后的本地提交!
如何撤消上一次的Git提交?
为了恢复所有的事情,我们需要重置到HEAD之前的提交。
-
如果您不想保留您所做的更改:
git reset --hard HEAD^
-
如果你想保持你的改变:
git reset --soft HEAD^
现在检查你的git日志。 它会显示我们上次提交已被删除。
使用reflog来查找正确的状态
git reflog
REFLOG之前重置
select正确的reflog(在我的情况下是f3cb6e2)并键入
git reset --hard f3cb6e2
之后,回购HEAD将重置为该HEADid logging后重置
最后,reflog如下图所示
REFLOG FINAL
只需重置它执行下面的命令使用git
:
git reset --soft HEAD~1
解释一下: git reset
作用是什么,它基本上被reset
为你想要返回的任何提交,然后如果你把它和--soft
键结合起来,它会返回,但是保存在你的文件中,所以你回到刚添加文件的阶段, HEAD
是分支的头部,如果你和~1
结合(在这种情况下你也使用HEAD^
),它将只返回一个你想要的提交。 ..
我在下面的图片中为您创build了更多细节中的步骤,包括可能在实际情况下发生并提交代码的所有步骤:
第一次运行:
git reflog
它会显示您在存储库中执行的所有可能操作,例如,提交,合并,拉取等。
然后做:
git reset --hard ActionIdFromRefLog
“重置工作树到最后的提交”
git reset --hard HEAD^
“清除工作树中的未知文件”
git clean
请参阅 – Git快速参考
注意:这个命令会删除你以前的提交,所以谨慎使用! git reset –hard更安全 –
其他方式:
签出要恢复的分支,然后将本地工作副本重新设置为您希望成为远程服务器上最新的一个提交(在它将会再见之后的所有内容)。 为此,在SourceTree中,我右键单击并select“将BRANCHNAME重置为此提交”。
然后导航到您的存储库的本地目录并运行以下命令:
git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME
这将清除当前仓库中所有提交之后的所有提交,但仅限于该分支。
inputgit log
并find最后一个提交哈希码,然后input:
git reset <the previous co>
在我的情况下,我不小心犯了一些我不想要的文件。 所以我做了以下工作:
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来validation结果
有两个主要场景
你还没有推送提交
如果问题是您提交的额外文件(并且您不希望存储库中的文件),则可以使用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存储库中删除。
您已经推送提交
你可以应用相同的解决scheme,然后使用-f
选项来执行git push
,但不build议使用,因为它会改变远程历史logging(可能会导致您的存储库混乱)。
相反,你必须做不提交--amend
(记住这个关于-amend:该选项重写最后一次提交的历史)。
撤消上次提交: –
git reset --soft HEAD^
或者git reset --soft HEAD~
这将撤消上次提交。
这里 – --soft
意味着重置到分期。
HEAD~
或HEAD^
表示在HEAD之前移动提交。
将上次提交replace为新提交:
git commit --amend -m "message"
它将用新的提交replace上次的提交。
使用SourceTree (Git的graphics工具)查看您的提交和树。 您可以通过右键单击来手动重置它。
很简单,在你的命令行中运行:
git reset --soft HEAD~
要重置为以前的版本,请永久删除所有未提交的更改:
git reset --hard HEAD~1
这篇文章有一个很好的解释 ,如何去各种情况下 (提交已完成以及推或OR只是一个提交,在推)之前:
http://christoph.ruegg.name/blog/git-howto-revert-a-commit-already-pushed-to-a-remote-reposit.html
从这篇文章中,我看到的最简单的命令 是通过它的提交ID恢复以前的提交 :
git revert dd61ab32