除非您非常了解大型提交中发生的所有更改,否则这可能会非常乏味。
通常,非常大(坏大)的提交涉及许多不同的更改。您需要做的是从概念上隔离所有这些更改并重写不同的提交。
我建议根据以下 4 个标准来分解变更:
[新] 涉及与单个识别的技术级功能相关的所有代码(与可能涉及多个技术级功能的用户级相反)
[RFG] 任何行为不变的变化。保留执行的行为和 API(接口)
[CHG] 实施任何代表规范/要求变更的内容
[修复]任何可能改变行为的更改,以使其符合编码背后的意图。
然后,git-wise 这就是你需要做的:
git checkout <bad commit SHA1> -b CULPRIT
这将创建一个“CULPRIT”分支。我始终保留此作为参考,因为您可能需要对以下步骤执行许多繁琐的迭代。作为旁注,沿途保留部分引用会有所帮助(作为分支或标签)。
git reset HEAD^ --mixed
这将撤消提交,就好像该提交中的所有更改都作为未暂存更改的补丁应用到先前提交中一样。然后使用
git add --patch
您可以更改这些更改的子集。请毫不犹豫地使用 [s]plit 选项来逐行单独选择更改。有时,您无法避免手动选择所需更改的版本。并重新暂存为我上面建议的 NEW、RFG、CHG、FIX 方案中分解的多个提交,并根据需要重写任意数量的提交。
请注意:
- 暂存一个无法编译的新提交
- 暂存一个新的提交,该提交会产生“微不足道”的运行时错误(例如段错误)
- 需要合并才能使事情正常工作的子提交
...因为目标是让二等分工作。此外,通过 git diff 新的 HEAD 提交来确保您的新提交与旧提交相同,以确保您没有引入进一步的更改。
一开始这很痛苦,需要大量练习,但是一旦你足够擅长这样做,你将成为整个团队崇拜的调试之神,然后可以以 NEW 的形式传播小提交的福音, CHG、RFG 和 FIX。