嚴華 发表于 2024-12-5 04:09:52

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

一、媒介

项目开辟阶段使用分支是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。
https://i-blog.csdnimg.cn/direct/3b14d3b28ba342a7b06a8ea32c439caa.png
三、解决方案

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^^   # 回退所有内容到上上个版本
https://i-blog.csdnimg.cn/direct/613cf48d651940b4bace7a8fe4874ecc.png
留意⚠️:审慎使用git reset –hard 参数,它会删除回退点之前的全部信息!
HEAD 说明:
https://i-blog.csdnimg.cn/direct/0d9da8226d7d47878a0a26dc61ed3aba.png
3.3 应用git cherry-pick commit-version

cherry-pick可以把别的分支上的commit一个个抽离出来,合并到指定分支上。用法如下:
$ git cherry-pick <commitHash>
针对以上问题,起首找到revert前的commitid,应用git cherry-pick commit-version把commit提交一个个找回。
如果在cherry-pick 过程中出现了辩论 ,可以使用git cherry-pick --continue 跳过此版本;如果想中途退出cherry-pick ,可以使用git cherry-pick --abort下令,实行完cherry-pick 后可以使用git cherry-pick --quit 下令。
3.3.1 cherry-pick 应用示例

举例来说,代码堆栈有master和feature两个分支。
https://i-blog.csdnimg.cn/direct/e794a18a6c504668b79bff3ee209b0ad.png
如今将提交f应用到master分支。
# 切换到 master 分支
$ git checkout master

# Cherry pick 操作
$ git cherry-pick f
上面的操作完成以后,代码库就酿成了下面的样子。
https://i-blog.csdnimg.cn/direct/dcdee6986ccc49ffae844fc50cf69f68.png
从上面可以看到,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详解》

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Git进阶(十九):git revert 导致 merge 代码丢失问题修复