如何在Git分支A含其他提交时移除分支B的所有提交?
问题描述
我从master分支衍生出两个分支A和B。首先在分支B上进行开发,随后将B的代码合并到分支A;之后其他开发者持续将他们的分支合并到A(提交d、e、f);接着我在分支B上新增提交d',并再次将B合并到A。提交历史示意图如下:
初始状态
*--*--*--* <- master \ a--b--c <- A \ a'--b'--c' <- B
步骤1:将B合并到A
*--*--*--* <- master \ a--b--c \ \ \ a'--b'--c' <- A \ a'--b'--c' <- B
步骤2:其他开发者向A合并提交d、e、f
*--*--*--* <- master \ a--b--c \ \ \ a'--b'--c'--d--e--f <- A \ a'--b'--c' <- B
步骤3:在B新增提交d'并合并到A
*--*--*--* <- master \ a--b--c \ \ \ a'--b'--c'--d--e--f--d' <- A \ a'--b'--c'--d' <- B
现在需要从分支A中移除分支B的所有提交(a'--b'--c'--d'),该如何操作?
解决方案
根据你的分支历史,要移除A分支中所有来自B的提交(a'、b'、c'、d'),分两种场景处理:
场景1:分支A仅在本地,未推送到远程仓库
这种情况可以用交互式rebase直接改写本地历史,操作更干净:
- 切换到分支A:
git checkout A - 启动交互式rebase,定位到合并B之前的最后一个提交(也就是提交
c):git rebase -i c - 在弹出的文本编辑器中,找到所有属于B分支的提交(a'、b'、c'、d'),将这些提交行开头的
pick替换为drop,保存并退出编辑器。 - 完成后,A分支的提交历史会回到
c节点,并保留其他开发者的d、e、f提交,最终历史结构如下:*--*--*--* <- master \ a--b--c--d--e--f <- A \ a'--b'--c'--d' <- B
场景2:分支A已推送到远程公共仓库
此时不能改写公共历史(会导致其他开发者同步出错),需用git revert逐个抵消B分支提交的修改:
- 切换到分支A:
git checkout A - 找到B分支所有提交的哈希值(a'、b'、c'、d'),依次执行revert命令:
每次执行git revert <a'的提交哈希> git revert <b'的提交哈希> git revert <c'的提交哈希> git revert <d'的提交哈希>git revert会生成一个新的提交,用来抵消对应提交的代码修改,执行过程中可能需要解决冲突,按常规冲突处理流程操作即可。 - 完成后,A分支的历史会新增4个revert提交,代码效果上完全移除了B分支的所有修改,同时保留了d、e、f的提交,最终历史结构如下:
*--*--*--* <- master \ a--b--c \ \ \ a'--b'--c'--d--e--f--d'--revert-d'--revert-c'--revert-b'--revert-a' <- A \ a'--b'--c'--d' <- B
内容的提问来源于stack exchange,提问作者SniperPro
相关产品推荐
相关产品推荐

