【转载】git 回退版本
原文地址:Git revert该如何用? 作者:一杯代码
最近有个新闻,国内的Gitee被工信部提名了,可能以后国内程序员会转向Gitee托管代码。
然而不管你用Gitee还是Github,你总是要用git的,个人认为你很难用另外的工具去取代git如今的地位。
如今git的使用在程序员圈应该算是很普及的,但是git有些操作可能不是很容易理解,尤其是文档一上来就是一堆命令的解释,也不管大多数情况下是否会用的到。
这就会让学习git的人一头雾水,我明明就想看某一个命令怎么用,一上来那么多参数到底是要干嘛。
而这篇文章我主要想讲一下在git里想revert该怎么办,我会以场景来讲解,就是说你工作中可能会遇到这样的场景,然后你该怎么操作,我觉得这才是一个正常的入门讲解,一上来一堆命令参数的解释我为啥不直接看文档。
既然我主要讲revert,那你应该对git有那么一点点认知,如果一点也不知道,这篇文章也不适合你。
首先我们先假设我们有一条这样的commit历史:
A1 ---> A2 ---> A3 ---> A4 ---> A5 ---> A6
当前的最新提交是A6,git的HEAD指向A6。
我知道你想问什么,HEAD是什么鬼,你现在不用深究这个,总之你正常的commit情况下,最新的commit就是指向的HEAD,你如果不确定,可以在你的repo里面运行git log,看看HEAD是不是指向你的最新的commit。
场景一
你可能在某一天发现,A4以及之后的commit都不能要,这种情况怎么办。
第一种情况
如果你的commit还没有push到远程仓库,并且你本地没有commit的内容也都不想要了,那么你可以这么做:
git reset --hard HEAD~3
这个HEAD~3是什么,别急,看下面:
A1 ---> A2 ---> A3 ---> A4 ---> A5 ---> A6
5 ---> 4 ---> 3 ---> 2 ---> 1 ---> 0
懂了吗,从HEAD开始,依次的序号。
注意:--hard参数表示会清除所有没有commit的内容,并且会修改commit历史,也就是说A4,A5,A6的历史没了。(可能大多数情况这样并不好,但是作为个人项目或者自己在一个branch上实验各种东西,这个是合适的,因为实验的commit历史记录并没有什么价值,可能就是一大堆wip)
第二种情况
如果你的commit已经都push到了远端仓库,或者你不想修改commit历史,那么最好用git revert。
我们这个例子你可以这样做:
git revert --no-commit HEAD~2^..HEAD
或者
git revert --no-commit HEAD~3..HEAD
举一反三一下,很容易明白这个命令的意思,我们要revert A4到A6,范围表示HEAD~2^..HEAD
或者 HEAD~3..HEAD
。
m..n
表示范围的话,开闭类似(m, n]
,学过数学的都知道是啥意思吧,这也是为啥从HEAD~3
开始,HEAD~2^
表示HEAD~2
的parent,所以等价HEAD~3
。
--no-commit
表示revert之后不自动commit,意思是,你运行完这个命令,你的repo会revert这些代码,然后这些代码处于未commit状态,我比较喜欢这样,因为可以在你commit之前,清楚的看到是不是你想revert的代码。
如果一切就绪,commit你的revert,那么现在这个commit历史就是是:
A1 ---> A2 ---> A3 ---> A4 ---> A5 ---> A6 ---> B
没错,你的A4,A5,A6依然在历史里,新的B commit就是你revert掉A4,A5,A6之后的结果,其实就是A3的状态,但历史都保留了。
这个范围revert还有一个等价的写法,就是:
git revert --no-commit HEAD HEAD~1 HEAD~2
直接指定commit。
场景二
以上第一种场景是revert一个范围,但是也有另一种场景,你可以就用上面提到的git revert,比如你想只revert A5,这样做:
git revert --no-commit HEAD~1
这个会产生一个新的commit,revert掉A5之后的commit,然后会产生的commit记录如下:
A1 ---> A2 ---> A3 ---> A4 ---> A5 ---> A6 ---> C
C就是去除了A5之后的内容。
总结
两个场景,覆盖大部分工作场景,你如果有更复杂的需求,你可能也不需要看我的文章,对于简单需求,与其被各种参数搞得头昏脑胀,不如就记住这几个命令,重要的记住这几个命令执行后的效果,做到安全可控。
我知道你可能觉得命令的细节我并没有解释清楚,但是据我的经验,对于很多新手来说,当你开始解释细节的时候,之前所有为了新手理解所做的简化和总结,会慢慢被所谓的详细讲解给搞糊涂,所以,当你不懂一个东西的时候,就记住我总结的命令,记住它,用它,先别管其他的,就用它,时间长了,再去看细节,效果会好很多很多。