Git的回滚和撤销操作

更新时间:2023-05-12 20:50:17 阅读: 评论:0

Git的回滚和撤销操作
魏主是谁简述
版本控制系统可以帮助我们回到某个历史版本,那么在 Git ⾥,如何回滚操作,撤销某次提交或恢复到某个提交呢?以下我们根据需要回滚的常见场景来介绍这些操作的最佳办法:
本地修改但未 push 到远程
撤销本地的修改
场景: 你修改了⽂件,但还没有 commit 。你想要恢复到修改前 —— 就像上次 commit 的时候⼀模⼀样。
补肾固精⽅法: git checkout -- <bad filename>
原理: git checkout会把⼯作⽬录⾥的⽂件修改到 Git 之前记录的某个状态。你可以提供⼀个你想返回的分⽀名或特定 SHA ,或者在缺省情况下,Git 会认为你希望 checkout 的是HEAD,当前 checkout 分⽀的最后⼀次 commit。
提醒:你⽤这种⽅法“撤销”的任何修改真的会完全消失。因为它们从来没有被提交过,所以之后 Git 也⽆法帮助我们恢复它们。你要确保⾃⼰了解你在这个操作⾥扔掉的东西是什么!(也许可以先利⽤git diff确认⼀下)
重置本地的修改
景: 你在本地 commit 了⼀些东西(还没有 push),但是你发现这些提交是错误的不需要的,你希望撤销前⾯的⼏次提交 —— 就像它们从来没有发⽣过⼀样。
⽅法: git ret <last good SHA>
原理: git ret会把你的代码库历史返回到指定的 SHA 状态。这样就像是这些提交从来没有发⽣过。缺省情况下,git ret会保留⼯作⽬录。这样,提交是没有了,但是修改内容还在磁盘上。这是⼀种安全的选择。我俩的故事
⽰例说明:以下我们模拟了 4 次提交,最近的 3 次提交是错误的,我们希望回到如下红框处所⽰的“正确的提交”
第⼀步,我们找到要回到的这次提交的 commit,如上图所⽰是 f5142d4e5a69a9250daa7612de399d78d0db1fd8
第⼆步,执⾏ git ret f5142d4e5a69a9250daa7612de399d78d0db1fd8
执⾏后,我们可以看到通过 3 次 commit 提交的内容取消暂存但仍然被保留到了⼯作⽬录。你可以继续编辑修正错误后,然后继续通过 git add 、git commit 操作进⾏提交。
但通常我们会希望⼀步就“撤销”提交以及修改内容 —— 这就是--hard选项的功能。但这个是⼀个危险操作,这是 ret 命令唯⼀的危险⽤法,--hard 选项会真正地销毁数据,它强制覆盖了⼯作⽬录中的⽂件。只有当你确定废弃修改时使⽤ --hard 选项。虽然我们可以通过下⼀节介绍的 reflog 来找回曾经 commit 过的,但对于未 commit 过的内容将⽆法恢复了。
表示绿色的词语有哪些
在撤销本地修改之后再恢复
场景: 你提交了⼏个 commit,然后⽤git ret --hard撤销了这些修改(见上⼀节使⽤了 --hard 选项),然后你意识到 ret 错了,想要恢复。⽅法: git reflog和git ret或git checkout
原理: git reflog对于恢复项⽬历史是⼀个超棒的资源。你可以恢复⼏乎任何东西 —— 任何你 commit 过的东西 —— 只要通过 reflog。
你可能已经熟悉了git log命令,它会显⽰ commit 的列表。git reflog也是类似的,不过它显⽰的是⼀个HEAD发⽣改变的时间列表.
注意事项:
它涉及的只是HEAD的改变。在你切换分⽀、⽤git commit进⾏提交、以及⽤git ret撤销 commit 时,HEAD会改变,但当你⽤git checkout -- <bad filename>撤销时(正如我们在前⾯讲到的情况),HEAD并不会改变 —— 如前所述,这些修改从来没有被提交过,因此
reflog 也⽆法帮助我们恢复它们。
git reflog不会永远保持。Git 会定期清理那些 “⽤不到的” 对象。不要指望⼏个⽉前的提交还⼀直躺在那⾥。
reflog只存在于本地 —— 这是⼀个记录你在你⾃⼰的仓库⾥做过什么的⽇志。其他⼈拷贝的仓库⾥的引⽤⽇志不会和你的相同;⽽你新克隆⼀个仓库的时候,reflog 是空的,因为你在仓库⾥还没有操作。你的reflog就是你的,只是你的。你不能⽤git reflog来恢复另⼀个开发者没有 push 过的 commit。
⽰例说明:通过 git reflog 命令可以查看引⽤⽇志
表见代理那么,怎么利⽤ reflog 来“恢复”之前“撤销”的 commit 呢?它取决于你想做到的到底是什么:
如果你希望准确地恢复项⽬的历史到某个时间点,⽤git ret --hard <SHA>
如果你希望重建⼯作⽬录⾥的⼀个或多个⽂件,让它们恢复到某个时间点的状态,⽤git checkout <SHA> -- <filename>
如果你希望把这些 commit ⾥的某⼀个重新提交到你的代码库⾥,⽤git cherry-pick <SHA>
修正最后⼀个 commit 消息
场景: 你在最后⼀条 commit 消息⾥有个笔误,已经执⾏了git commit -m "Fxies bug #42",但在git push之前你意识到消息应该是 “Fixes bug
#42″。
⽅法: git commit --amend或git commit --amend -m "Fixes bug #42"
原理: git commit --amend会⽤⼀个新的 commit 更新并替换最近的 commit ,这个新的 commit 会把任何修改内容和上⼀个 commit 的内容结合起来。如果当前没有其他新的修改,这个操作就只会把上次的 commit 消息重写⼀遍。如果你想通过添加或修改⽂件来更改提交的快照,也可以通过类似的操作来完成。通过修改⽂件然后运⾏git add或git rm⼀个已追踪的⽂件,随后运⾏git commit --amend拿⾛当前的暂存区域并使其做为新提交的快照。
已经 push 到远程
回滚其中的某个 commit
场景: 你已经执⾏了git push, 把你的修改发送到了远程,但是这些 commit 中其中⼀个是有问题的,你需要回滚那⼀个 commit.
⽅法: git revert <SHA>
原理: git revert会产⽣⼀个新的 commit,它和指定 SHA 对应的 commit 是相反的(或者说是反转的)。如果原先的 commit 是“物质”,新的commit 就是“反物质” —— 任何从原先的 commit ⾥删除的内容会在新的 commit ⾥被加回去,任何在原先的 commit ⾥加⼊的内容会在新的commit  ⾥被删除。
这是 Git 最安全、最基本的撤销场景,因为它并不会改变历史 —— 所以你现在可以git push 新的“反转” commit 来抵消你错误提交的commit。
⽰例说明:
第⼀步,确认要回滚的 commit。如下,需要回滚红框的 commit 的内容,保留红框上⾯的 commit 的内容,如要回滚 commit
3f4e41ee4c7ffe2a49ffab0343185c03e5c57f30
第⼆步,执⾏ git revert 3f4e41ee4c7ffe2a49ffab0343185c03e5c57f30
这时,可以看到产⽣了⼀个新的 commit
第三步,回滚完成后执⾏ git push 提交到远程,远程可以看到如下内容
回滚到某个 commit
场景: 你已经执⾏了git push, 把你的修改发送到了远程,但是这些 commit 都是有问题的,⽽且这些 commit 没有合并线,你需要回滚到之前
的 commit.(注:如果这些 commit 中有合并线,即有过其他合并,这个⽅法不适⽤)
⽅法: git revert HEAD..<SHA>
原理: git revert会产⽣⼀个新的 commit,它和指定 SHA 对应的 commit 是相反的(或者说是反转的)。如果原先的 commit 是“物质”,新的commit 就是“反物质” —— 任何从原先的 commit ⾥删除的内容会在新的 commit ⾥被加回去,任何在原先的 commit ⾥加⼊的内容会在新的commit  ⾥被删除。
这是 Git 最安全、最基本的撤销场景,因为它并不会改变历史 —— 所以你现在可以git push 新的“反转” commit 来抵消你错误提交的commit。
⽰例说明:
第⼀步,确认要回滚到的 commit。如下,需要回滚到红框的 commit 的内容,也就是保留红框⾥的 commit 的内容,要回滚到
88c5918b02c48c7f306559592c40aa1ffc3139fe 这个 commit
第⼆步,执⾏ git revert 88c5918b02c48c7f306559592c40aa1ffc3139fe..HEAD,HEAD 是最新的版本,这个表⽰要从 HEAD 开始,回滚到88c5918b02c48c7f306559592c40aa1ffc3139fe 版本,也就是要逐个回滚上图的 HEAD(59f0201fbf7940204dcffa7fdb951539f4934c9f)、983c12915afade3c7dbab4eab8d3a0ef1b0f0eb7、(如果中间还有的话)直到保留 88c5918b02c48c7f306559592c40aa1ffc3139fe 这个commit
这时,可以看到产⽣了⼀个新的 commit
第三步,回滚完成后执⾏ git push 提交到远程,远程可以看到如下内容
回滚某次合并
场景: 你完成了⼀次合并,并执⾏了git push, 把你的修改发送到了远程,但是这次合并的内容是有问题的,你需要回滚到合并之前.
⽅法: git revert -m [要被保留下来的那个⽗节点] [要回滚的 commit]
-m [要被保留下来的那个⽗节点]标记指出 “mainline” 需要被保留下来的⽗结点。当你完成⼀个合并,,新提交有两个⽗结点:第⼀个是⽬标分⽀,第⼆个是要合并⼊⽬标分⽀的源分⽀的最新 commit。对于上述场景,如从 branch 合并到 master,要回滚 branch 合并到 master 的内容,这⾥就是要保留第⼀个⽗节点,也就是git revert -m 1
原理: git revert会产⽣⼀个新的 commit,它和指定 SHA 对应的 commit 是相反的(或者说是反转的)。如果原先的 commit 是“物质”,新的commit 就是“反物质” —— 任何从原先的 commit ⾥删除的内容会在新的 commit ⾥被加回去,任何在原先的 commit ⾥加⼊的内容会在新的commit  ⾥被删除。
这是 Git 最安全、最基本的撤销场景,因为它并不会改变历史 —— 所以你现在可以git push 新的“反转” commit 来抵消你错误提交的commit。
⽰例说明:如从 branch 合并到 master,要回滚 branch 合并到 master 的内容
第⼀步,确认要回滚的合并的 commit。如下,需要回滚红框的合并产⽣的 commit 的内容,这时合并产⽣的 commit 是
5a4228c92c359a53bc99cf17e68eebc59763fbc2
第⼆步,执⾏ git revert  -m 1 5a4228c92c359a53bc99cf17e68eebc59763fbc2,-m 1指保留 master 的
commit,5a4228c92c359a53bc99cf17e68eebc59763fbc2 是要回滚的 commit
这时,可以看到产⽣了⼀个新的 commit
第三步,回滚完成后执⾏ git push 提交到远程,远程可以看到如下内容。由于我们只回滚合并操作,因此如下“merge 后的提交”是在合并后的提交,这个 commit 的修改内容不会被回滚。
阿什利科尔回滚后,被回滚的合并的提交依然在提交历史中。如果你尝试再次合并被回滚的 branch 分⽀, Git 会感到困惑:
这时,可以通过撤消那次回滚的的合并,然后再创建⼀个新的合并提交完成再次的合并操作,如上就是对回滚产⽣的 commit 进⾏ revert:手鼓音乐前10首
幼儿园消防安全知识

本文发布于:2023-05-12 20:50:17,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/889566.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:提交   回滚   修改
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图