我在长变基时遇到的一个问题是必须解决冗余冲突。假设我有一个带有一系列提交的分支,它不断修改一个函数,而最终提交完全删除了该函数。
当我这样做时rebase master
,Git 会天真地依次应用每个提交。这意味着我需要用 master 的提示来解决这些提交中的每一个——即使最终这些工作都被浪费了。
有什么好的方法来处理这种情况?也许我应该为整个分支生成一个补丁,然后将其应用于 master?如果是这样,有什么办法可以保留一些历史吗?想法、建议等。
我在长变基时遇到的一个问题是必须解决冗余冲突。假设我有一个带有一系列提交的分支,它不断修改一个函数,而最终提交完全删除了该函数。
当我这样做时rebase master
,Git 会天真地依次应用每个提交。这意味着我需要用 master 的提示来解决这些提交中的每一个——即使最终这些工作都被浪费了。
有什么好的方法来处理这种情况?也许我应该为整个分支生成一个补丁,然后将其应用于 master?如果是这样,有什么办法可以保留一些历史吗?想法、建议等。
您想结合使用历史提交来git rerere
教授数据库(您可能已经拥有它)。这允许 git 自动使用从历史中学到的合并冲突解决方案。rerere
rerere-train.sh
/usr/share/doc/git/contrib/rerere-train.sh
警告:您基本上是通过盲目地使用历史字符串替换来修复冲突的合并,从而使 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
你可以使用git rerere
功能。
您必须使用 启用它git config --global rerere.enabled 1
,然后,您解决的每个冲突都会存储以供以后使用,并且解决方案会在相同的上下文中重新应用。
您可以使用 来检查存储的分辨率git rerere diff
。
查看本教程以获取更多信息。
为什么不在squash
初始交互式 rebase 中将多余的补丁放在一起(首先重新排序它们以便它们在一起),以便您清除序列的“修改然后删除”方面。在此阶段,您可以对提交中的帅哥进行选择性处理(例如,使用 git gui)。然后,这将为您提供更好的最终干净变基序列。
(这是我对问题的第二个答案。在第二次阅读时,我认为最初的问题可能与我最初理解的问题有点不同。)
我理解这个问题,因为您有一个与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
. 从长远来看,不仅你的变基会更容易,而且历史是可读的。
因此,在上面的示例中,可以rebase -i <old-enough-sha1>
将提交重新排序为 3+4+6+8、10、1+2+5+7+9、11+12,其中+
表示 squash。Git 也允许拆分和编辑现有的提交,但通常更容易保持提交非常小,然后再压缩其中的一些。请注意,在此示例中,即使原始提交编号 10 在原始第一次提交之前结束。这是正常的,反映了您的实施并不完美的现实。不过,这不需要存储在版本历史记录中。
在您的情况下,听起来您有一个功能分支,其中多个提交添加和删除相同的东西。将这些提交压缩为单个提交(可能最终没有更改,这没关系)。仅当功能分支看起来很干净时,才将您的功能分支重新设置为 master。绝对要学习使用git gui
或其他一些工具,使提交更改的行而不是文件变得容易。每个提交都应该是一个修改一个理智的东西集合的更改。如果您添加新功能 X,则同一提交不得修复现有功能 Y 或添加有关 Z 的缺失文档。即使对同一文件进行了这些更改也不行。对我来说,这就是 Linus Torvalds 所说的“文件无关紧要”的意思”。