详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)

文章目录

  • 1. 问题场景描述
    • 1.1 场景模拟
  • 2. 解决方案
    • 2.1 利用`git reset --hard`命令
    • 2.2 利用`git revert` 命令
    • 2.3 使用页面进行回滚(效果与Revert一致)

1. 问题场景描述

我的项目包含两个重要git分支:master(生产环境),develop(测试环境)。

正常的开发流程为:从master剪分支,然后进行开发,开发后合并到develop分支,当测试通过后合并到master分支进行上线。

所以,master分支和develop分支代码差别很大,包括:未上线的代码,针对develop做的特殊处理等等。

但某人错误操作,不小心从develop剪分支,最终合并到了master分支,造成develop的分支跑到了master分支上,造成生产问题。

所以需要对合并进行回退。

1.1 场景模拟

首先,我们master上有两个提交记录:

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第1张图片

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第2张图片

develop上也对应也有两个提交记录

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第3张图片

此时我们新建一个version-20221107的分支,本应该从master上剪,结果错误的从develop上剪了。

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第4张图片

此时,我们将version-20221107合并到master上(假设没有冲突):

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第5张图片

之后会发现,develop的代码出现在了master上。

我们来查看master的提交记录:

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第6张图片

会发现除了包含合并记录外,也包含develop的提交记录,这也是回退过程中最令人头疼的情况。

2. 解决方案

2.1 利用git reset --hard命令

说明:git reset --hard 命令是强制回到某一个版本,然后利用git push -f命令强制推到远程

优点:干净利落,回滚后完全回到最初状态。

缺点:

  1. 需要找到你要回滚的版本。如果再你合并后,又有很多提交记录,那你就很难找了。
  2. 完全删除了你指定版本之后的代码,很难找回
  3. 如果在你回滚前,有人从该分支剪出了代码,那么之后还会被合回来。
  4. 如果在你回滚前,有人提交了代码,那么你回滚后,他的代码就没了。
  5. 该分支不能是“保护分支”,否则无法强制推送,必须找管理员来做这个事。
    5

不管优点缺点吧,来试一下:

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第7张图片

我们是要回退到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提交记录,发现合并的都没了

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第8张图片

上述查找版本到reset的都可以用git reset --hard HEAD~1代替,HEAD~1表示回退到上一版本。不过个人推荐还是一步一步做,不容易出错


假设上述动作是第二天才做的,中间有一个人又从master上拉了一个version-202221108的分支:

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第9张图片

我们做回退的也不知道,这个时候假设他把version-20221108合并到master上,看看会发生什么情况:

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第10张图片

最后发现白回滚了,回滚的代码又回来了。这也缺点中的第三条。

不过用revert命令回滚可以避免该问题。

2.2 利用git revert 命令

说明revert 命令是“回滚”,即回滚某一次的操作。我们可以利用该来撤销合并错误。其原理为:撤销上一个版本的操作,会生成一个新的版本。相当于一次重新提交,只不过这次的提交的内容就是把上次提交的内容给还原。

优点

  1. 之前的错误提交记录可以找到。
  2. 如果别人在你回滚前剪出了分支,重新合并后不会有问题。
  3. 不需要管理员权限
  4. 如果回退前又有人提交了代码,也不会对他的提交造成影响。

缺点:不够干净,还会保留错误合并的提交记录。

接下来我们来实验下:

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第11张图片

目前,我们需要对合并操作进行回滚,也就是对70ca41f4这个提交。我们只需要使用如下命令:

git revert 70ca41f4 -m 1

-m 1 是固定的,可以理解保留当前分支的代码,回滚掉来源分支的代码。

在执行完该命令后,会弹出输入comment信息,确定后,进行push即可。

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第12张图片

之后可以看到生成了一条revert的记录,并且代码也回退到原状。

此时,我们再将version-20221108合并到master,结果如下(已处理冲突):

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第13张图片

可以看到,虽然version-20221108分支是在回滚前剪出的,但并不会把develop的代码合并进来。


假设有人在回滚前又提交了代码:

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第14张图片

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第15张图片

使用Revert命令并不会对其造成影响。

2.3 使用页面进行回滚(效果与Revert一致)

说明:直接使用gitlab页面进行操作,原理与使用revert命令一致。

优点

  1. 操作简单,与使用命令效果一致。
  2. revert有的优点,它基本都有

缺点:如果你回滚的版本后面有提交,那么页面无法自动完成,需要用命令。


首先,我们选择要回滚的合并提交记录:

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第16张图片

选择Revert

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第17张图片

选择要Revert的分支

详解Git合并(Merge)错误如何回退。(包括Reset, Revert和页面回滚三种,并说明其优缺点)_第18张图片

最后点击Revert就行了。

你可能感兴趣的:(Java,git,github)