Git revert该如何用?

4,160 阅读4分钟

最近有个新闻,国内的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之后的内容。

总结

两个场景,覆盖大部分工作场景,你如果有更复杂的需求,你可能也不需要看我的文章,对于简单需求,与其被各种参数搞得头昏脑胀,不如就记住这连个命令,重要的记住这几个命令执行后的效果,做到安全可控。

我知道你可能觉得命令的细节我并没有解释清楚,但是据我的经验,对于很多新手来说,当你开始解释细节的时候,之前所有为了新手理解所做的简化和总结,会慢慢被所谓的详细讲解给搞糊涂,所以,当你不懂一个东西的时候,就记住我总结的命令,记住它,用它,先别管其他的,就用它,时间长了,再去看细节,效果会好很多很多。

- EOF -

当你迷茫时

一杯咖啡,千行代码

欢迎关注公众号:一杯代码