3

假设我有一个分支 case-xyz,我在其中为案例 #xyz 工作,“实现 Hello World”。

在开发过程中,我添加了调试输出等,这不应该是最终提交的一部分。

我可以执行以下操作:

  • 分支到 case-xyz-debug 并仅在此处提交调试代码。
  • 偶尔将 case-xyz-debug 合并到 case-xyz 中。
  • 在 case-xyz 中提交应该进入最终补丁的内容。
  • 最后,“反向合并”case-xyz-debug,即删除来自该分支的所有更改,独立于它们何时合并到case-xyz。换句话说,这应该相当于从 case-xyz-debug 还原所有合并。

我知道在revert一个merge commit的时候,Git并没有忘记merge,即它仍然认为你已经合并了,所以只能通过revert的revert来重新merge。因此,只需删除最初在 case-xyz-debug 中提交的所有更改,如何记录是无关紧要的。但是,如果我也可以执行以下操作,那就太好了:

  • git checkout case-xyz
  • git checkout case-xyz-done
  • git "反向合并" case-xyz-debug

因为我可能想继续开发/调试:

  • git checkout case-xyz
  • 更改文件
  • git commit -am “哎呀,忘记了什么”
  • git checkout case-xyz-really-done
  • git "反向合并" case-xyz-debug

我希望我的意图很明确。如果这可以实现,但以完全不同的方式,我也会很高兴。

4

1 回答 1

0

作为我正常工作流程的一部分,我通过交互式变基定期做这种事情。我的提交包括调试日志记录、临时测试更改(fe 线程睡眠调用以测试计时问题、故意抛出异常以测试错误处理代码)、硬编码值以使在我的应用程序中更容易进行端到端测试而无需在 UI 中输入值等。我将这些东西放在单独的提交中;按照我自己的约定,如果提交日志消息全部大写,则表示不应将提交推送到远程。

当我准备好“反向合并”这些更改(删除它们)时,我通过交互式 rebase 这样做:

git rebase -i <id of branch point>

我只是删除了所有大写消息的提交。

(您实际上可以将其用于其他目的,例如重新排序它们以使它们都位于分支的开头,这对于git commit --amend您的实际工作很有用,或者将它们重新排序到最后,这在您想要推branch-point..<id of last real commit>送到远程,让你的“调试”提交完整并在当前历史行的末尾。)

知道是什么<id of branch point>可能有点痛苦;在我的工作流程中,我不想master在删除调试提交的同时将我的分支重新定位到 fe 的末尾;出于这个原因,我保留了一个本地浮动标签,我将其用作我简单调用的参考点rebase(这可能会令人困惑,但您可以选择任何您喜欢的名称)。如果这看起来工作量太大,那么使用git rebase -i `git merge-base HEAD master`可能是您的一个选择。

(我理解认为这是一种危险做法的论点,但我认为它们并不是特别有说服力;有上百万种方法可以用 SCM 击中自己的脚。你应该考虑将git rebase --abort和结合起来git reflog成为你的“逃生舱口”,以防您不小心删除了包含比调试代码更多的提交。)

高温高压

于 2012-10-11T20:23:30.380 回答