最近在开发中遇到了需要git版本回退的问题,特此记录一下了解到的两种回退方式。
0. 了解提交历史
git的版本回退需要了解git的提交历史,拿到你想回退的commitId。该查看命令为:
git log
一般到此就够了,如果你想了解更多,可以使用命令:
git show commitId
利用此命令,可以查看某次提交详细的信息(如merge的两个分支的commitId)
1. 使用git reset
命令格式:
git reset --soft/–hard commitId
该方式是通过移动HEAD指针的方式进行回退的。
这种提交方式有一个问题,单纯的本地回退是OK的,但是如果要回退的内容已经提交到远程仓库时,将此回退提交到远程仓库时将会失败,因为远程仓库的HEAD比当前分支更靠前,会提示你更新本地仓库。
对此有一个解决方法,就是将回退提交到远程仓库时,加上-f参数(强制提交):
git push -f origin master
相信你已经看到,reset可以加参数-hard 或 -soft。默认是 -soft。
- -soft 参数使用效果:该条commitId之 后(时间作为参考点)的所有commit的修改都会退回到git缓冲区中。啥意思?就是回退之后,但是你提交的内容并没有删除,还是在本地等待你add、commit、push
- -hard 参数使用效果:缓冲区中不会存储这些修改,git会直接丢弃这部分内容。
但是如果删完了之后又后悔了,想要恢复怎么办?
没问题,因为reset只是修改了HEAD指针指向的commitId,只要你能够找到reset前的commitId,然后再reset就行了。如果你不知道那次提交的commitId,可以使用以下命令查询:
git reflog
2. 使用git revert
命令格式:
git revert commitId
该方式使用一种类似“对冲”的方式进行“回退”,实际上是将commitId之后的修改再改回来,然后再提交一次。此方式可以提交到远程仓库,不用强制提交了。
有时候git自动给我们进行revert提交时,会存在一些冲突,这时候需要我们自己解决这些冲突,然后add、commit、push。。。流程走完,就回退完成了。
- 使用revert还有一种特殊情况:
如果要回退的是merge操作,直接操作会报类似如下错误:
$ git revert 05f1a67e2113cc785d132f425e654fa400913c57
error: commit 05f1a67e2113cc785d132f425e654fa400913c57 is a merge but no -m option was given.
fatal: revert failed
这里是因为merge操作的回滚涉及到了两个分支,所以需要使用-m参数指定回退的分支。
-m 取值一般为1 或 2,其中1代表主分支,使用-m 1则代表将主分支以外的分支revert掉