【问题标题】:Can I synthesize a branch in git that skips a single change set我可以在 git 中合成一个跳过单个更改集的分支吗
【发布时间】:2018-01-17 21:58:40
【问题描述】:
假设以下git 分支:A -> B -> C -> D -> E -> F -> G
我已通过git bisect 确定提交 C 引入了一个错误,但在分支顶部还原 C 引入的更改并不能解决问题。这向我表明,该分支的后续提交中还有其他错误。
有没有办法合成以下分支: A -> B -> D1 -> E1 -> F1 -> G1 ,其中 1 表示提交 C 中引入的更改不存在?然后我会在该分支上运行git bisect 以确定是否找到其他错误。 [希望这不需要重复多次]
【问题讨论】:
标签:
git
testing
git-bisect
【解决方案1】:
是的:
git checkout -b newbranch <specifier-for-B>
git cherry-pick <specifier-for-C>..<specifier-for-G>
这些<specifier>s 可以是原始哈希ID,或分支名称,或带有~<em>number</em> 的分支名称以倒计时number 首次提交,等等。诀窍是创建一个新分支,该分支在最后一个好的提交处结束,然后在除已知的错误提交之外的其余可能好的提交中挑选。
一旦你有了这个新分支,你可以使用git rebase -i 或git rebase --onto <target> <exclude> 来删除更多的提交,如果你愿意的话。
【讨论】:
-
注意,顺便说一句,Jonathan.Brink's method 基本上是一样的,只是他从新分支开始,与旧分支相同,然后让你删除提交。如果您必须重复删除,这可能会感觉更方便。不过,它确实需要一个交互式 rebase 步骤(或花哨的rebase --onto 步法)。
【解决方案2】:
您可以交互地变基并删除该提交。
首先创建测试分支:
git checkout -b test
接下来,启动变基:
git rebase -i C^ # the parent of C
当您在交互式 rebase 屏幕中时,删除包含 commit C 的行。
这将使save 分支有效匹配A -> B -> D1 -> E1 -> F1 -> G1,您可以继续测试。
如果您发现 C 是您需要删除的唯一提交,另一种选择是还原它,这样您就不需要推送任何修改已推送提交的历史记录:
git checkout master # get back to where you started
git revert C # will create a revertion commit
git push # will only push 1 new commit, the inverse of C