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


    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命令强制推到远程

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

    缺点:

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

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

    在这里插入图片描述

    我们是要回退到master commit2, 但是在实际中,我们并不能一眼就看出哪些是develop的提交记录,所以很难定位到要回退到哪个版本,所以要配合如下命令:

    查看分支的提交情况

    git reflog
    
    • 1

    输出:

    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
    
    • 1
    • 2

    可以看到,通过该命令,并不会出现像gitlab上那么多提交记录,所以9e47366就是我们要回滚的分支。

    接下来,就是强制回滚:

    git reset --hard 9e47366
    
    • 1

    然后强制push

    git push -f
    
    • 1

    然后再来看下git提交记录,发现合并的都没了

    在这里插入图片描述

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


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

    在这里插入图片描述

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

    在这里插入图片描述

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

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

    2.2 利用git revert 命令

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

    优点

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

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

    接下来我们来实验下:

    在这里插入图片描述

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

    git revert 70ca41f4 -m 1
    
    • 1

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

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

    在这里插入图片描述

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

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

    在这里插入图片描述

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


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

    在这里插入图片描述

    在这里插入图片描述

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

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

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

    优点

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

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


    首先,我们选择要回滚的合并提交记录(注意:这里要选择的是“你要回滚的提交,而不是你要回滚到哪个版本”):

    在这里插入图片描述

    选择Revert

    在这里插入图片描述

    选择要Revert的分支

    在这里插入图片描述

    最后点击Revert就行了。

  • 相关阅读:
    ARM官方汇编与ARM GNU汇编中的伪操作
    使用Element UI 的el-pagination组件实现分页效果
    模版代码:Express 中间件快速入门
    ES09# Filebeat配置项及吞吐调优项梳理
    “一老一幼”的智慧化守护,网易和中国电信交出“三年答卷”
    Tested采访扎克伯格:揭秘四款VR原型机更多细节
    Leetcode 1541. Minimum Insertions to Balance a Parentheses String (括号问题好题)
    面试突击48:死锁的排查工具有哪些?
    你需要的导航网站,这里都有
    python:遗传算法(Genetic Algorithm,GA)求解23个测试函数
  • 原文地址:https://blog.csdn.net/zhaohongfei_358/article/details/127729172