当前位置: 首页 > news >正文

Git进阶(十九):git revert 导致 merge 代码丢失问题修复

文章目录

    • 一、前言
    • 二、问题分析
    • 三、解决方案
      • 3.1 方案一:官方推荐方法
      • 3.2 方案二:reset 方法
      • 3.3 应用git cherry-pick commit-version
        • 3.3.1 cherry-pick 应用示例
      • 3.4 git reset 和git revert的区别
    • 四、拓展阅读

一、前言

项目开发阶段使用分支是feature_xxx,将feature_xxx分支merge到master之后,这时发现刚代码有bug,需要回版本回退,点击revert按钮。

将本地的原分支feature_xxx代码修改后提交到远程分支,发起 Merge 到 Master 的申请会发现,feature_xxx分支和 master 分支的差异 commit 只有 feature_xxx 分支 revert 后的提交记录,之前的代码变动都没有了。

二、问题分析

对于master而言,已经合并过feature_xxx,master包含feature_xxx的commitid,这些提交不会参与diff,所以不会显示出两个分支的不同。

revert 操作实际是只是进行了一次逆向 commit,将 merge 的代码进行回滚,但是 commit 的记录还存在。也就是说,feature_xxx 上面存在的待提交代码,其实已经是 master 的过去代码,属于已提交过的状态,所以不会显示 different。

在这里插入图片描述

三、解决方案

3.1 方案一:官方推荐方法

该核心思想就是:对 revert 的那次提交记录再次 revert 。这个操作能够将本要提交的代码,放置到最新的HEAD,其commitid要比master高,所以会重新diff

首先,切换到 master 分支,并基于 master 分支拉出一个分支 revert_tmp。作为 master 的副本,revert_tmp 的作用就是保存 revert 的提交记录;

git checkout master
git checkout -b revert_tmp

其次,在 master 分支上找到 revert 的那条提交记录的版本号,回滚至之前的版本(版本号可以通过“git log”命令,或者从网页端查看);

git log         # 查询<版本号>,格式,如:f2c3b544166eec612ea6814d6cd19aeef46824f8
git revert <版本号>  

然后,切换到 feature_xxx 分支上,将 revert_tmp 这个分支 merge 到 feature_xxx 分支上。

git checkout feature_xxx 
git merge revert_tmp 
git push -f

最后,在 feature_xxx 重新提交对 master 的 merge 申请,会发现 revert 之前的代码都回来了。

3.2 方案二:reset 方法

revert 不同,采用 git reset 将 head 向后移动到上一次 merge 前的 commit 版本,会丢弃所有的 merge commit 记录(revert 不会丢弃,是逆向 commit),所以,再次合并不会出现记录不显示或者冲突的问题。

git reset HEAD^    # 回退所有内容到上一个版本 
git reset HEAD^^   # 回退所有内容到上上个版本 

在这里插入图片描述
注意⚠️:谨慎使用 git reset –hard 参数,它会删除回退点之前的所有信息!

HEAD 说明:
在这里插入图片描述

3.3 应用git cherry-pick commit-version

cherry-pick可以把其它分支上的commit一个个抽离出来,合并到指定分支上。用法如下:

$ git cherry-pick <commitHash>

针对以上问题,首先找到revert前的commitid,应用git cherry-pick commit-versioncommit提交一个个找回。

如果在cherry-pick 过程中出现了冲突 ,可以使用git cherry-pick --continue 跳过此版本;如果想中途退出cherry-pcik ,可以使用git cherry-pick --abort命令,执行完cherry-pick 后可以使用git cherry-pick --quit 命令。

3.3.1 cherry-pick 应用示例

举例来说,代码仓库有master和feature两个分支。

在这里插入图片描述
现在将提交f应用到master分支。

# 切换到 master 分支
$ git checkout master# Cherry pick 操作
$ git cherry-pick f

上面的操作完成以后,代码库就变成了下面的样子。

在这里插入图片描述
从上面可以看到,master分支的末尾增加了一个提交f。

git cherry-pick命令的参数,不一定是提交的哈希值,分支名也是可以的,表示转移该分支的最新提交。

$ git cherry-pick feature

上面代码表示将feature分支的最近一次提交,转移到当前分支。

Cherry pick 支持一次转移多个提交。

$ git cherry-pick <HashA> <HashB>

上面的命令将 A 和 B 两个提交应用到当前分支。这会在当前分支生成两个对应的新提交。

如果想要转移一系列的连续提交,可以使用下面的简便语法。

$ git cherry-pick A..B 

上面的命令可以转移从 A 到 B 的所有提交。它们必须按照正确的顺序放置:提交 A 必须早于提交 B,否则命令将失败,但不会报错。

注意,使用上面的命令,提交 A 将不会包含在 Cherry pick 中。如果要包含提交 A,可以使用下面的语法。

$ git cherry-pick A^..B 

git cherry-pick命令的常用配置项如下。

  • -e--edit

打开外部编辑器,编辑提交信息。

  • -n--no-commit

只更新工作区和暂存区,不产生新的提交。

  • -x

在提交信息的末尾追加一行(cherry picked from commit …),方便以后查到这个提交是如何产生的。

  • -s--signoff

在提交信息的末尾追加一行操作者的签名,表示是谁进行了这个操作。

  • -m parent-number--mainline parent-number

如果原始提交是一个合并节点,来自于两个分支的合并,那么 Cherry pick 默认将失败,因为它不知道应该采用哪个分支的代码变动。

-m配置项告诉 Git,应该采用哪个分支的变动。它的参数parent-number是一个从1开始的整数,代表原始提交的父分支编号。

$ git cherry-pick -m 1 <commitHash>

上面命令表示,Cherry pick 采用提交commitHash来自编号1的父分支的变动。

一般来说,1号父分支是接受变动的分支(the branch being merged into),2号父分支是作为变动来源的分支(the branch being merged from)。

3.4 git reset 和git revert的区别

git reset是回退到某个版本之前,在这个版本后提交的代码都没有了,git revert 是单纯的撤销某次操作,不影响后续的提交记录(但是如果是要撤销merge操作,请慎用此命令,因为有可能出现无法再次merge的情况,如果是撤销常规的commit 提交,可以使用)。

四、拓展阅读

  • 《Git进阶(二):git revert 用法》
  • 《Git进阶(十二):git merge 用法详解》
  • 《Git进阶(十八):git rebase详解》

http://www.mrgr.cn/news/67689.html

相关文章:

  • 鸿蒙开发案例:水平仪
  • 4070显卡只要一毛钱?这个双十一太疯狂了
  • Android笔记(三十一):Deeplink失效问题
  • Java Agent使用
  • 《Keras3 深度学习初探:开启Keras3 深度学习之旅》
  • 蓝桥杯真题——三角回文数(C语言)
  • Qos基本原理+园区网络
  • kelp protocol
  • 什么是兼容性测试
  • hhdb数据库介绍(8-4)
  • JavaScript void 运算符
  • OpenJDK Vendor下载选择
  • 【工具】数字打乱器
  • 102. 二叉树的层序遍历 队列+迭代
  • 中仕公考:天津市25年公务员出公告啦
  • 入门网络安全工程师要学习哪些内容(详细教程)
  • 人民法院案例库:执行案件中未组织当事人对评估材料进行质证,评估程序是否违法
  • 对一个数据库中的所有表格的所有字符串字段 ,进行文本替换 将 A字符串, 替换为 B字符串
  • 0-基于图的组合优化算法学习(NeurIPS 2017)(未完)
  • 让股票数据分析从此如此简单
  • 什么是进销存?进销存系统都有哪些类型?
  • 【测试语言篇四】Python进阶篇之json模块
  • 初识网络编程
  • 【电子设计】STM32CubeIDE安装
  • 浅玩IO流
  • 【Spring】——SpringBoot项目创建