系列文章目录
手把手教你安装Git,萌新迈向专业的必备一步
GIT命令只会抄却不理解?看完原理才能事半功倍!
常用GIT命令详解,手把手让你登堂入室
GIT实战篇,教你如何使用GIT可视化工具
GIT使用需知,哪些操作会导致本地代码变动
文章目录
经过前面的学习,GIT的基本原理以及使用想必大家已经是门清了,但是在实际操作中,很多同学还是会有误操作的情况。本文就讲下各种场景下代码如何回退
📕作者简介:战斧,从事金融IT行业,有着多年一线开发、架构经验;爱好广泛,乐于分享,致力于创作更多高质量内容
📗本文收录于 GIT 专栏,有需要者,可直接订阅专栏实时获取更新
📘高质量专栏 云原生、RabbitMQ、Spring全家桶 等仍在更新,欢迎指导
📙Zookeeper Redis kafka docker netty等诸多框架,以及架构与分布式专题即将上线,敬请期待
一、commit 前回退
场景:当我们在工作区做了一些改动,或者ADD了一些新文件,但还没有提交时
1. 整个工程回退
此时如果我们想整个工程回退到上一个提交版本,可以使用 reset
或 checkout
,如
git reset --hard HEAD
我们在这里使用了 – hard, 这样会丢弃工作区的所有改动以及暂存区的新增文件,并将指针移动到上一个提交版本,即把所有文件恢复至上一个提交点。
如果你使用IDEA的话,那你可以这样操作,当然Idea中需要提前安装GIT插件,可参考《手把手教你安装Git,萌新迈向专业的必备一步》
2. 单个文件回退
但有的时候我们仅仅是一个文件搞砸了,不需要回退整个工程,仅需要回退某个文件到上次提交点的话,可以使用 checkout
把某次提交的某个文件给取出来
git checkout <commit-hash> -- <file-path>
比如 我们想将example.txt文件回退到上一次 commit 的状态,就可以这么用
git checkout -- example.txt
如果你使用IDEA的话,则可以使用里面的 Rollback
操作达到同样的效果
3. 新增文件回退
对于一些新文件,如果已经ADD过,那么它就进入了暂存区,如果想把它从暂存区移出来,可以通过命令来实现
git reset HEAD <file-name>
或者Idea的 Rollback 此时也有同样的效果
二、commit 后回退
场景:如果我们比较不幸,把使用 commit 后,才发现有错误,我们就需要把本地仓库也回退掉了
1. 回退到上个版本
我们可以使用以下命令撤销上一次提交
git revert HEAD
这会创建一个新的提交,将上一次提交的改动反转回去。如果你使用Idea的话,可以直接在提交记录中进行Revert Commit
需要注意的是,这并非真正意义的撤销提交
,而是把原始内容重新覆盖回去,所以revert
会产生一次新的提交记录。而如果想要真正的“撤销提交”,可以使用IDEA中的Undo Commit
这其实是运用了下面的 git reset --soft
机制,回退并保留工作区的代码
2. 回退到指定版本并放弃后续修改
当然有的时候我们发现的时候,本地已经commit了好几次了,这个时候我们想回到某一次提交的版本,就需要自己指定了回退的位置了
git reset --hard <commit-hash>
其中是需要回退到的提交版本的哈希值,每一次提交的 hash 值我们都可以在 git log 里看到,这会丢弃指定版本之后的所有提交,并将指针移动到指定版本。Idea 的话可以这么操作
或者在Log中直接选择对应的提交记录进行 reset
,两种方式都一样
3. 回退到指定版本但保留工作区
如果我们commit
后才发现错误,其实我们更常见的想法是,回溯-改掉-重新提交,那么我们就要求回溯后,我们本地的代码不会跟着回退,我们可以基于目前的代码改完后再次提交。这样我们就可以这么用
git reset --soft <commit-hash>
这样我们本地仓库的位置会停留在你指定的提交点,但是工作区的东西不会受到影响。IDEA的操作和上面一样,只是弹窗里选择 Soft 即可
三、push 后回退
场景:当我们在本地误操作后,没有及时发现,已经将错误内容push到远程仓库时
一般来说,push上去,按严重程度可分为两种情况,
push
进特性分支或自己的独立分支,但没有merge
进主分支push
后,错误代码已经进入主分支
在团队开发中,一般当错误被误
push
进主分支时,情况就比较严重了,此时为了避免问题复杂化,或引起不必要的冲突,强烈建议其他组员暂停向该分支合并
此时若要修复,其实就是下面这两步
1. 修复本地内容
这一步其实就是上面提到的《commit 后回退》章节,可以自己选一种方式来修复
2. 推送至远程
本地修改好以后,再将本地回退的修改强制推送到远程仓库,就使用push
命令
git push origin <分支名> 或 git push -f origin <分支名>
请注意,如果使用了git push -f命令来强制推送修改,这可能会导致他人的工作丢失。因此,在执行此操作前,请确保与团队成员进行充分的沟通,并确保你有足够的理由和权利来修改远程仓库的历史记录。
四、恢复误删分支
如果我们误删除了一个分支,可以使用以下命令进行恢复:
git reflog
这会列出所有的提交历史,找到被删除的分支的最后一次提交的哈希值。然后使用以下命令进行恢复:
git branch <branch-name> <commit-hash>
其中是需要恢复的分支名称,是被删除分支的哈希值。这会重新创建被删除的分支。
五、回退命令对比
通过上面的内容,不难发现在Git中,有几个常用的命令用于实现回退功能:reset
、revert
和checkout
,我们接下来就简要分析下它们的用法、原理,以及最终回退的效果是否有所不同。
1. reset命令
reset
命令可以将HEAD指针和当前分支指向指定的提交。根据其参数 soft
、 mixed
、 hard
的不同,其最终的效果是不同的
- git reset
--soft
<commit-hash>:将HEAD和当前分支指向指定提交,但不改变暂存区和工作目录的内容。通过这种方式,可以撤销之前的提交,但保留修改的文件和刚ADD的文件 - git reset
--mixed
<commit-hash>:将HEAD和当前分支指向指定提交,且重置暂存区,但不改变工作目录的内容。通过这种方式,可以撤销之前的提交,并保留当前修改的文件 - git reset
--hard
<commit-hash>:将HEAD和当前分支指向指定提交,并将暂存区和工作目录的内容恢复为与指定提交相同。这种方式会彻底取消之前的提交,并删除相关的修改。
简而言之,三种 reset 方式都能重置到指定的提交点,该位置之后的提交记录都会消失,但可以自由选择是否保存暂存区和工作区里的代码.soft 全保留,mix 只保留工作区, hard 则是重置所有啥都不剩
2. revert命令
revert
命令用于撤销指定的提交,创建一个新的提交来表示撤销的变更,它的标准样式就是
git revert <commit-hash>
效果是创建一个新的提交,将之前的提交的变更内容恢复到当前分支中,同时保留历史记录。因为它能指定某一次提交进行恢复,最终新增一次提交,那么它有可能会发生冲突,这个时候就需要手动控制冲突修复了
3. checkout命令
checkout命令用于切换分支或恢复文件的状态。其标准样式为
git checkout <commit>
在回退功能中,可以使用checkout
命令来切换到之前的提交,从而实现回退.与上面两种方式比,checkout
即不会产生提交,也不会修改分支内容(即分支指向的位置,不清楚分支真正概念的可以去看《GIT命令只会抄却不理解?看完原理才能事半功倍!》)。只是单纯切换分支,所以本地分支是会被更改掉的。
而且 checkout
还能把单个文件恢复到任意提交点的样子,其样式为
git checkout <commit-hash> -- <file-path>