git代码回滚操做

昨天说到用git reset进行回滚操做,还有git revert的操做,它们的区别以下:git

git reset

git reset的做用是还原Index的状态或修改本地分支HEAD的位置。这个命令适合用于从某个提交点开始,从新开新的分支。好比,若是某个提交以后的代码咱们都不要了,就能够在本地reset至指定commit,而后开一个新的branch继续新的开发(原来分支在远程上没有发生任何变化的)。bash

使用git reset是不影响远程分支的,一切都在本地发生。若是回退须要很快影响远程分支的,应该使用git revert。spa

两种状况code

第一种状况:只是在本地commit,尚未push到远程分支,可经过如下命令实现:开发

git reset --soft|--mixed|--hard <commit_id>
git push 本地分支名称 远程分支名称 --force

这里的<commit_id>就是每次commit的SHA-1,能够在git log里查看到源码

--mixed: 只是将git commit和index 信息回退到某个commit版本,仍会保留该commit_id以后提交的代码
--soft: 只回退到commit信息到某个版本,不涉及index的回退,会保留源码,若是还须要提交, 直接commit便可.
--hard: 源码会回退到某个版本,commit和index 都会回退到某个版本. (这种方式会改变本地代码仓库源码)it

固然有人在push代码之后,也使用 reset --hard <commit_id> 回退代码到某个版本以前,可是这样会有一个问题, 线上的代码还是回退以前的,线上commit, index都没有变, 当你把本地代码修改完提交的时候你会发现全是冲突.....ast

 

git revert

假如某些旧提交咱们不想要了,而又不肯经过 本身修改这些旧提交所产生的代码,而后从新提交的方式 来完成,这个时候咱们就能够把这项工做交给revert命令。class

Git Revert原理:根据你要回退的提交所作的改动作方向相反的改动,而后从新提交代码,使代码达到没有这些旧提交所能达到的状态。原理

若是对于git revert的回退策略还没理解,这样讲也许你就能理解了:回退旧的提交必然会致使当前最新代码发生变化,好比以前某个提交加了一行代码,那么回退就是在相同位置减一行代码。Git不会真的把旧提交抛弃,若是直接抛弃,历史记录就追踪不到了。所以,旧提交实际上是没动的,Git只是根据旧提交反着作了一遍,这才致使最新的代码发生了改变。只有把revert命令回退致使的改动从新提交,revert命令才算真的完成并生效,不然效果只至关于修改了工做树的文件而已。注意:revert以后须要push到远程分支上其余用户才能看到回退发生的改动。

使用git revert会出现的问题

由于git revert是用新提交覆盖旧提交,所以,被覆盖的旧提交等于不会被采用了。若是两个分支(假设是master和A分支)先合并再用revert回滚,以后又合并(A合并到master),就会发如今master分支上,A分支第一次合并以前的修改大部分不见了。这是由于从时间的发生顺序来看,A分支第一次合并以前的修改发生在revert以前,revert发生在后,而 revert抛弃了A第一合并以前的修改,那么再此合并Git就认为你永远抛弃了A第一次以前的修改。

要解决这个问题,须要把revert产生的提交再revert一次(至关于恢复以前的旧提交)。

 

二者区别

注意:git revert是用一次新的commit来回滚以前的commit,git reset是直接删除指定的commit,看似达到的效果是同样的,其实彻底不一样。

第一:若是已经push到线上代码库, reset删除指定commit之后, 你git push可能致使一大堆冲突,可是revert 不会;
第二:若是在往后现有分支和历史分支须要合并的时候, reset 恢复部分的代码依然会出如今历史分支里,但revert 方向提交的commit 并不会出如今历史分支里(注意!!!); 第三: reset 是在正常的commit历史中, 删除了指定的commit, 这时 HEAD 是向后移动了, 而 revert 是在正常的commit历史中再commit一次, 只不过是反向提交, 他的 HEAD 是一直向前的。

相关文章
相关标签/搜索