我遇到长期重组的一个问题是必须解决多余的冲突。假设我有一个带有一系列提交的分支,它们一直在修改一个函数,最后的提交完全删除了这个函数。
当我rebase master
时,Git天真地依次应用每个提交。这意味着我需要使用master的提示解决每个提交 - 尽管最终这些工作都被浪费了。
处理这种情况的好方法是什么?也许我应该为整个分支生成一个补丁,并将其应用于master?如果是这样,有什么方法可以保留一些历史记录吗?思想,建议等。
答案 0 :(得分:10)
您希望使用git rerere
结合使用rerere-train.sh
从历史提交中教授rerere
数据库(您可能已在/usr/share/doc/git/contrib/rerere-train.sh
处获得)。这允许git自动使用从历史记录中学习的合并冲突解决方案。
警告:你基本上是通过盲目地使用历史字符串替换来修复冲突的合并,让git重写源代码。您应该在rebase之后查看所有冲突的合并。我发现gitk
可以正常工作(它只显示冲突解决方案作为合并补丁)。我只有rerere
的好经验,你可能没那么幸运。基本上,如果您的历史记录确实包含损坏的合并(即,技术上不正确的合并然后在以下提交中修复),您不希望使用历史记录中的rerere
,除非您想要同样破坏合并自动完成。
长话短说,你就跑了
git config --global rerere.enabled 1
bash /usr/share/doc/git/contrib/rerere-train.sh --all
然后是你真正想做的变种,它应该神奇地起作用。
在全球范围内启用rerere
后,您将来不再需要了解历史记录。只有在启用rerere
之前已经完成冲突解决后才能使用rerere
才需要学习功能。
PS。我找到了另一个问题的类似答案:https://stackoverflow.com/a/4155237/334451
答案 1 :(得分:7)
您可以使用git rerere
功能。
您必须使用git config --global rerere.enabled 1
启用它,之后,您解决的每个冲突都会被存储以供以后使用,并且在相同的上下文中重新应用解析。
您可以使用git rerere diff
检查存储的分辨率。
请查看此tutorial以获取更多信息。
答案 2 :(得分:4)
为什么不在初始交互式rebase中将squash
冗余补丁放在一起(首先重新排序它们以便它们在一起),以便清除序列中的“修改然后删除”方面。在这个阶段你可以选择提交中的帅哥(例如使用git gui)。这将为您提供更好的序列,以便最终获得最终清洁。
答案 3 :(得分:2)
(这是我的第二个问题答案。在二读时我认为最初的问题可能与我最初的理解有点不同。)
我理解这个问题,因为你有master
的开发分支并行。通常这种分支样式称为特征分支,我绝对鼓励使用它们。
应始终尝试保持功能分支清洁。在实践中,您需要一个功能分支,如果您从未犯过任何错误,那么该功能分支将提交您已经完成的功能。对我来说,这意味着承诺了很多,后来git rebase -i
来修复错误,当我后来了解这些错误时。
当您的功能分支准备好时,它应该看起来像
而不是
如果您然后将功能分支重新绑定到最新的master
分支,则更改很高,只有提交Fix existing API Y for corner case Z
可能会导致冲突。如果该提交是修改现有 API的最小更改,那么修复冲突应该很容易。此外,只有当其他一些提交修改了您的最小更改所触及的行时,才会产生冲突。
如果你做功能分支和rebase功能分支而不是合并(我的首选样式是rebase,以便快进是可能的,然后做git checkout master && git merge --no-ff feature-branch-x
并记录合并提交中的整个事情 - 这允许保持完整的分支历史,并允许GUI工具在需要时轻松浏览功能)在将这些分支重新定位到master
之前,您肯定希望keep your feature branches clean。不仅你的rebase会更容易,但从长远来看,历史是可读的。
所以在上面的例子中,可以rebase -i <old-enough-sha1>
,重新提交的顺序为3 + 4 + 6 + 8,10,1 + 2 + 5 + 7 + 9,11 + 12 {{1}壁球。 Git也允许拆分和编辑现有的提交,但通常更容易保持提交非常小,然后再压缩其中一些。请注意,在此示例中,即使原始提交号10在最初的第一次提交之前结束。这是正常的,反映了您的实施并不完美的现实。但是,这不需要存储在版本历史中。
在您的情况下,听起来您有一个功能分支,其中多个提交添加和删除相同的东西。将这些提交压缩为单个提交(可能最终没有变化,这是可以的)。仅在功能分支看起来干净时才将功能分支重新定位到主分支。绝对要学会使用+
或其他一些工具来轻松提交更改行而不是文件。每次提交都应该是一个改变,修改一个理智的东西集合。如果添加新功能X,则相同的提交不得修复现有功能Y或添加有关Z的缺少文档。即使对同一文件进行了这些更改也是如此。对我来说,这就是Linus Torvalds在说“files do not matter”时的意思。