Git父分支提交变更后,如何高效传递到子分支并仅处理一次冲突?
问题描述
从develop分支拉了feat-1,写完代码提了PR等着合到develop。等PR的期间,又基于feat-1开了feat-2做依赖功能,做完feat-2再开feat-3做依赖feat-2的功能,分支结构是这样的:
develop \ feat-1 \ feat-2 \ feat-3
现在得在feat-1里加些变更,这些变更和feat-2、feat-3会冲突。想问两个事儿:
- 提交完
feat-1的变更后,怎么把变更传到feat-2和feat-3? - 要是逐个合并的话得重复处理相同冲突,有没有只处理一次冲突的办法?
解决方案
一、常规逐个合并的办法
如果按顺序逐个合并,步骤是这样:
- 更新feat-1并提交
切到feat-1分支,改完代码提交:git checkout feat-1 # 完成代码修改 git add . git commit -m "fix: 补充feat-1的变更" - 把feat-1合并到feat-2
切到feat-2,合并feat-1,解决冲突后提交:git checkout feat-2 git merge feat-1 # 手动解决冲突文件 git add <冲突文件路径> git commit -m "merge: 合并feat-1的变更,处理冲突" - 把feat-2合并到feat-3
切到feat-3,合并feat-2,处理剩下的冲突(大概率会碰到和feat-2里一样的冲突):git checkout feat-3 git merge feat-2 # 解决冲突 git add <冲突文件路径> git commit -m "merge: 合并feat-2的变更,处理冲突"
这种方法的问题就是相同冲突得重复处理,效率较低。
二、只处理一次冲突的高效办法
方法1:用git rebase --onto链式变基
变基能把分支的提交重新放到目标分支的最新提交后面,处理完feat-2的冲突后,feat-3变基时一般不会再碰到重复冲突:
- 确保feat-1是最新的
先确认feat-1的变更已经提交完毕,没有未保存的修改。 - 把feat-2变基到更新后的feat-1上
切到feat-2,执行变基,这时候只需要处理一次冲突:git checkout feat-2 git rebase feat-1 # 手动解决冲突 git add <冲突文件路径> git rebase --continue # 如果feat-2有多个提交,可能需要重复解决冲突直到变基完成 - 把feat-3变基到更新后的feat-2上
切到feat-3,变基到最新的feat-2,这时候因为feat-2已经处理过和feat-1的冲突,feat-3里大概率不会再出现相同冲突,顶多处理feat-3自己独有的代码冲突:git checkout feat-3 git rebase feat-2 # 有新冲突就解决,没有的话直接完成变基
方法2:用git rerere自动复用冲突解决方案
Git的rerere功能会记录你解决冲突的方式,下次碰到一模一样的冲突时,会自动帮你解决,不用再手动改:
- 开启rerere功能
可以全局开启(所有Git仓库都生效),也可以只在当前仓库开启:# 全局开启 git config --global rerere.enabled true # 仅当前仓库开启 git config rerere.enabled true - 处理第一次冲突并记录方案
切到feat-2,合并feat-1,手动解决冲突后提交,这时候Git会自动记住你怎么解决这个冲突的:git checkout feat-2 git merge feat-1 # 手动解决冲突 git add <冲突文件路径> git commit -m "merge: 合并feat-1变更,记录冲突解决办法" - 把变更传到feat-3
切到feat-3,合并feat-2,碰到相同冲突时Git会自动帮你解决,你只需要确认一下然后提交就行:git checkout feat-3 git merge feat-2 # Git自动解决重复冲突,直接提交 git commit -m "merge: 合并feat-2变更,自动复用冲突解决方案"
这个方法特别适合经常碰到相同冲突的场景,能省不少重复劳动。
内容的提问来源于stack exchange,提问作者Aniket Banyal
相关产品推荐
相关产品推荐

