文章目录
1. 问题场景描述
我的项目包含两个重要git分支:master(生产环境),develop(测试环境)。
正常的开发流程为:从master剪分支,然后进行开发,开发后合并到develop分支,当测试通过后合并到master分支进行上线。
所以,master分支和develop分支代码差别很大,包括:未上线的代码,针对develop做的特殊处理等等。
但某人错误操作,不小心从develop剪分支,最终合并到了master分支,造成develop的分支跑到了master分支上,造成生产问题。
所以需要对合并进行回退。
1.1 场景模拟
首先,我们master上有两个提交记录:
develop上也对应也有两个提交记录
此时我们新建一个version-20221107的分支,本应该从master上剪,结果错误的从develop上剪了。
此时,我们将version-20221107合并到master上(假设没有冲突):
之后会发现,develop的代码出现在了master上。
我们来查看master的提交记录:
会发现除了包含合并记录外,也包含develop的提交记录,这也是回退过程中最令人头疼的情况。
2. 解决方案
2.1 利用
git reset --hard
命令
说明:
git reset --hard
命令是强制回到某一个版本,然后利用
git push -f
命令强制推到远程
优点:干净利落,回滚后完全回到最初状态。
缺点:
- 需要找到你要回滚的版本。如果再你合并后,又有很多提交记录,那你就很难找了。
- 完全删除了你指定版本之后的代码,很难找回
- 如果在你回滚前,有人从该分支剪出了代码,那么之后还会被合回来。
- 如果在你回滚前,有人提交了代码,那么你回滚后,他的代码就没了。
- 该分支不能是“保护分支”,否则无法强制推送,必须找管理员来做这个事。 5
不管优点缺点吧,来试一下:
我们是要回退到
master commit2
, 但是在实际中,我们并不能一眼就看出哪些是develop的提交记录,所以很难定位到要回退到哪个版本,所以要配合如下命令:
查看分支的提交情况
git reflog
输出:
70ca41f (HEAD -> master-test, origin/master-test) HEAD@{0}: commit (merge): Merge remote-tracking branch 'origin/version-20221107' into master-test
9e47366 HEAD@{1}: checkout: moving from master to master-test
可以看到,通过该命令,并不会出现像gitlab上那么多提交记录,所以
9e47366
就是我们要回滚的分支。
接下来,就是强制回滚:
git reset --hard 9e47366
然后强制push
git push -f
然后再来看下git提交记录,发现合并的都没了
上述查找版本到reset的都可以用
git reset --hard HEAD~1
代替,
HEAD~1
表示回退到上一版本。不过个人推荐还是一步一步做,不容易出错
假设上述动作是第二天才做的,中间有一个人又从master上拉了一个
version-202221108
的分支:
我们做回退的也不知道,这个时候假设他把
version-20221108
合并到master上,看看会发生什么情况:
最后发现白回滚了,回滚的代码又回来了。这也缺点中的第三条。
不过用
revert
命令回滚可以避免该问题。
2.2 利用
git revert
命令
说明:
revert
命令是“回滚”,即回滚某一次的操作。我们可以利用该来撤销合并错误。其原理为:撤销上一个版本的操作,会生成一个新的版本。相当于一次重新提交,只不过这次的提交的内容就是把上次提交的内容给还原。
优点:
- 之前的错误提交记录可以找到。
- 如果别人在你回滚前剪出了分支,重新合并后不会有问题。
- 不需要管理员权限
- 如果回退前又有人提交了代码,也不会对他的提交造成影响。
缺点:不够干净,还会保留错误合并的提交记录。
接下来我们来实验下:
目前,我们需要对合并操作进行回滚,也就是对
70ca41f4
这个提交。我们只需要使用如下命令:
git revert 70ca41f4 -m 1
-m 1
是固定的,可以理解保留当前分支的代码,回滚掉来源分支的代码。
在执行完该命令后,会弹出输入comment信息,确定后,进行push即可。
之后可以看到生成了一条revert的记录,并且代码也回退到原状。
此时,我们再将
version-20221108
合并到master,结果如下(已处理冲突):
可以看到,虽然
version-20221108
分支是在回滚前剪出的,但并不会把develop的代码合并进来。
假设有人在回滚前又提交了代码:
使用Revert命令并不会对其造成影响。
2.3 使用页面进行回滚(效果与Revert一致)
说明:直接使用gitlab页面进行操作,原理与使用revert命令一致。
优点:
- 操作简单,与使用命令效果一致。
- revert有的优点,它基本都有
缺点:如果你回滚的版本后面有提交,那么页面无法自动完成,需要用命令。
首先,我们选择要回滚的合并提交记录:
选择Revert
选择要Revert的分支
最后点击Revert就行了。
版权归原作者 iioSnail 所有, 如有侵权,请联系我们删除。