总有一天你会遇到下面的问题:
- 改完代码匆忙提交,上线发现有问题,怎么办?赶紧回滚。
- 改完代码测试也没有问题,但是上线发现你的修改影响了之前运行正常的代码报错,必须回滚。
这些开发中很常见的问题,所以 git
的取消提交,回退甚至返回上一版本都是特别重要的。大致分为下面 2
种情况:
一、没有 push
这种情况发生在你的本地代码仓库,可能你 add
,commit
以后发现代码有点问题,准备取消提交,用到下面命令回退到某个版本:
1 | git reset [--soft | --mixed | --hard] |
上面常见三种类型
mixed
会保留源码,只是将 git commit
和 index
信息回退到了某个版本。
1 | git reset 默认是 --mixed 模式 |
soft
保留源码,只回退到 commit
信息到某个版本。不涉及 index
的回退,如果还需要提交,直接 commit
即可。
hard
源码也会回退到某个版本,commit
和 index
都回回退到某个版本。(注意,这种方式是改变本地代码仓库源码)
二、已经 push
2.1 方法一
使用 git reset --hard <commit...>
回退本地代码到某个版本。
使用 git push --force
将本次变更强行推送至服务器(因为你线上的代码没有变,线上 commit
,index
都没有变,所以必须使用强制推送)。这样在服务器上的最后一次错误提交也彻底消失了。
注意:这样操作比较比较危险,例如:在你的 commit
之后别人又提交了新的 commit
,那在你强制推送之后,那位仁兄的 commit
也跟着一起消失了,所以不建议这样操作。
2.2 方法二
使用以下命令:
1 | git revert <commit-ish>... |
git revert
用于反转提交,用一个新提交来撤销某次提交,执行 revert
命令时要求工作树必须是干净的。
revert
之后你再 git push
既可以把线上的代码更新。(这里不会像 reset
造成冲突的问题)
revert
使用需要先找到你想回滚版本唯一的 commit
标识代码,可以用 git log
或者在 adgit
搭建的 web
环境历史提交记录里查看。
1 | git revert c011eb3c20ba6fb38cc94fe5a8dda366a3990c61 |
通常,前几位即可:
1 | git revert c011eb3 |
三、revert 与 reset 比较
git revert
是用一次新的 commit
来回滚之前的 commit
,git reset
是直接删除指定的 commit
。
看似达到的效果是一样的,其实完全不同。
3.1 上面我们说的如果你已经 push
到线上代码库, reset
删除指定 commit
以后,你 git push
可能导致一大堆冲突。但是 revert
并不会。
3.2 如果在日后现有分支和历史分支需要合并的时候,reset
恢复部分的代码依然会出现在历史分支里。但是 revert
方向提交的 commit
并不会出现在历史分支里。
3.3 reset
是在正常的 commit
历史中,删除了指定的 commit
,这时 HEAD
是向后移动了,而 revert
是在正常的 commit
历史中再 commit
一次,只不过是反向提交,他的 HEAD
是一直向前的。