如何撤销Git中的所有操作
当你完成一个新的提交时,Git会存储一个快照);存储库在当前时刻的状态;您可以使用Git将项目回滚到任何以前的版本。
下面,我将列出几个需要“撤销”的常见场景,并展示如何使用Git来完成这些操作。
一、取消一个公* * *修改撤消一个“公”修改。
场景:你刚刚用git push把本地的修改推送到GitHub,然后你意识到提交有错误。您想要取消此提交。
使用撤消命令:git revert
发生了什么:git revert将基于给定SHA的相反值创建一个新的提交。如果旧提交是“物质”,那么新提交是“反物质”——从旧提交中移除的所有东西都将被添加到新提交中,从旧提交中添加的所有东西都将从新提交中移除。
这是Git最安全和最简单的“撤销”场景,因为它不会修改历史记录——您现在可以通过在git push下的revert之后提交来纠正错误。
其次,修改最新的提交信息,修复最后的提交消息。
场景:你只是在最终提交中输入了错误的单词。例如,您键入了git commit-m“Fxies bug # 42”,但是在执行git push之前,您意识到您应该键入“Fixes bug #42”。
使用撤销命令:git commit -amend或gitcommit-amend-m“修复bug # 42”。
发生了什么:git commit–amend将更新这个错误提交,并用一个新的包含所有刚刚错误提交的更改的错误提交来替换它。由于没有分阶段提交,所以这次提交实际上只是重写了之前的提交信息。
第三,取消局部修改撤消“局部”修改
场景:当你的猫在键盘上爬行时,你正在编辑的文件恰好被保存,你的编辑器就崩溃了。您此时没有提交代码。您希望撤消该文件中的所有更改——将该文件返回到上次提交时的状态。
使用撤销命令:gitcheckout-
发生了什么:git checkout将工作目录中的文件更改为git之前已知的状态。您可以提供您想要返回的分支的名称或者一个精确的SHA代码,Git还会检查头部——默认情况下——也就是当前分支的最后一次提交。
注意:这样“撤销”的修改真的会消失。它们永远不会被提交。所以Git无法恢复它们。此时,一定要清楚自己在做什么!(也许可以用git diff来确定)
第四,重置局部修改重置“局部”修改
情况:你已经在本地做了一些提交(还没有推送),但是一切都很糟糕,你想取消最后三次提交——就像从来没有发生过一样。
使用撤销命令:git reset或gitreset-hard。
发生了什么:git reset将您的仓库记录回滚到SHA指定的最后一次提交,而那些提交似乎从未发生过。默认情况下,git reset保留工作目录。虽然这些提交的内容已经消失了,但是内容仍然在磁盘上。这是最安全的方法,但是通常你想用一个命令“撤销”所有的提交和本地修改,那么请使用- hard参数。
动词 (verb的缩写)撤销"本地"后重做。
场景:你提交了一些内容,用git reset -hard撤销了这些更改(见上图),突然意识到:你想撤销这些更改!
使用撤销命令:git reflog和git reset,或者git checkout。
发生了什么:git reflog是恢复项目历史的好方法。您可以通过git reflog恢复几乎任何提交的内容。
您可能熟悉git log命令,它可以显示提交列表。Gitleflog与此类似,只是Gitleflog显示的是磁头更换次数的列表。
一些解释:
1.只有头会变。当您切换分支,用git commit提交更改,或用git reset取消提交时,头将会更改。但是当你使用git checkout -的时候,头是不会变的。(如上所述,那些更改根本没有提交,所以reflog无法帮助我们恢复。)
2.git reflog不会永远存在。Git会定期清理那些“不可及”的对象。不要指望在reflog中找到几个月前的提交记录。
3.reflog只属于你。你不能推送你的reflog来恢复其他开发者的无推送提交。
因此,如何合理使用reflog来检索之前“未完成”的提交?这取决于你真正想做什么:
1.如果想恢复某个提交的项目历史,请使用gitreset-hard。
2.如果您想在工作目录中恢复提交的一个或多个文件而不改变提交历史,请使用git checkout -
3.如果您想准确地回滚到提交,请使用git cherry-pick。
第六,这些东西又和分支有关,有分支
场景:您提交了一些变更,然后您意识到您在主分支上,但是您期望在特性分支上执行这些提交。
使用撤销命令:git分支功能、git重置-硬源/主和git检验功能。
发生了什么:您可能使用git checkout -b来创建一个新的分支,这是一种创建和检出分支的便捷方式——但是您不想立即切换分支。Git branch feature会创建一个名为feature的分支,该分支指向你最新提交的内容,但你仍然卡在主分支中。
Git reset - hard将主文件回滚到原始文件/主文件,并忽略所有新提交的文件。别担心,那些提交的东西还在特写里。
最后,git checkout将分支切换到feature,这将保持您最近的所有工作不变。
七、事半功倍及时分支节省九
场景:您已经基于主创建了一个新的特征分支,但是主分支远远落后于原点/主分支。既然主分支已经与源/主分支同步了,那么您希望立即提交特性下的代码,并且在主分支之后不远。
使用撤销命令:git checkout特性和git rebase master。
发生了什么:你可能输入了命令:git reset(但是没用——硬的,故意把这些提交保存在磁盘上),然后输入git checkout -b,然后重新提交修改,但是那样的话,你会丢失你的本地提交记录。然而,更好的办法是:
使用git rebase master可以做一些事情:
1.首先,它定位当前签出的分支和主节点之间的* * *公共祖先节点。
2.然后,它将当前签出的分支重置为祖先节点,并临时存储所有后续提交。
3.最后,它将当前检出的分支推到主文件的末尾,并在最后一次提交主文件后再次提交临时存储区中的那些更改。
八、批量撤销/批量恢复撤销/重做
情况:你开始朝着给定的目标开发功能,但是中途觉得用另一种方法更好。你已经有十几个投稿了,但是你只想要其中的几个,其他的都可以删除。
使用撤销命令:gitrebase-i。
发生了什么:-我将rebases设置为“交互模式”。Rebase启动如上所述的操作,但是当重新执行一个提交时,它会暂停并让您修改每个提交。
rebase–我将打开您的默认文本编辑器,然后列出正在执行的提交,如下所示:
前两列是最关键的:第一列是选择命令,它将根据第二列中的SHA代码选择相应的提交。默认情况下,rebase–我认为每一个变更都是通过pick命令提交的。
要取消提交,只需在编辑器中删除相应的行。如果你的项目中不再需要提交这些错误,可以直接删除上图中的1和3-4行。
如果您希望保留提交但修改提交信息,可以使用reword命令。也就是说,用reword(或r)替换命令关键字pick。你可能想现在修改提交消息,但它不会生效-rebase-我会忽略SHA列后的所有内容。现有的提交信息将帮助我们记住0835fe2代表什么。Git不会开始提示您重写那些新提交的消息,直到您敲rebase–I命令。
如果需要合并两个提交,可以使用命令squash或fixup,如下所示:
Squash和fixup都是“向上”的——使用这些合并命令(编者注:squash和fixup)的那些提交将与它们之前的提交合并:在上图中,0835fe2和6943e85将合并为一个提交,而38f5e4e和af67f82将合并为另一个提交。
使用squash时,Git会提示是否填写新的提交消息;修正将给出列表中第一个提交的提交信息。上图中,af67f82是一个“Ooops”消息,因为这个提交信息已经和38f5e4e一样了。但是,您可以为新提交的0835fe2和6943e85编写提交信息。
当您保存并退出编辑器时,Git将从上到下执行您的提交。您可以在保存之前修改这些提交的执行顺序。如果需要,可以合并af67f82和0835fe2,并按如下方式排序:
第九,修复早期提交修复早期提交。
情况:上次提交时留下了一个文件。如果之前提交的有你落下的就好了。你还没有推送,而且这个提交也不是最近的,所以不能用commit -amend。
使用撤销命令:gitcommit-squash和gitrebase-auto squash-I。
发生了什么:git commit–squash会新建一个提交,提交信息可能是这样的“Squash!早期提交.您也可以手写这些提交信息,commit -squash可以省去您的输入。
如果不想为合并的提交写信息,也可以考虑使用命令gitcommit-fixup。在这种情况下,您可以使用commit - fixup,因为您只想在rebase中使用以前的提交信息。
我将启动Rebase交互式编辑器,它将列出所有完成的挤压!和修复!提交,如下图所示:
当使用- squash和-fixup时,您可能不记得要修复的已提交的SHA代码,只记得可能是在一次或五次提交之前。您可以使用Git和~操作符手动检索它。head表示以前提交的HEAD。HEAD~4代表HEAD之前的四次投稿,合计* * *为前五次投稿。
X.停止跟踪被跟踪的文件。
场景:您意外地将application.log添加到了存储库中。现在,每次运行程序时,Git都会提示在application.log中有一个未提交的提交..你写了“*”。登录。Gitignore,但是还是没用——怎么告诉git“撤销”来跟踪这个文件的变化?
使用撤消命令:gitrm-cachedapplication.log。
事情经过:虽然。gitignore阻止Git跟踪文件的变化,即使之前没有被跟踪的文件存在,一旦文件被添加或提交,Git也会继续跟踪这个文件的变化。类似地,如果使用Git add–f来“强制”添加或覆盖。gitignore,git会继续监控变化。因此,最好不要使用–f来添加。gitignore文件。
如果你想删除应该被忽略的文件,gitrm–cached可以帮助你,把这些文件保存在磁盘上。因为这个文件现在被忽略了,所以您不会在git状态下看到它,也不会再次提交这个文件。
Git上就是这么撤销的。如果您想了解更多关于Git命令的用法,可以去下面的相关文档: