git 更智能的基础重建,避免重复工作?

ajsxfq5m  于 2023-01-15  发布在  Git
关注(0)|答案(4)|浏览(126)

我遇到的一个问题是必须解决冗余的冲突。假设我有一个分支,它的一系列提交不断修改一个函数,而最后一次提交完全删除了这个函数。
当我执行rebase master时,Git会很天真地依次应用每个提交,这意味着我需要使用master命令来解决每个提交--尽管最终这些工作都是浪费。
处理这种情况的好方法是什么?也许我应该为整个分支生成一个补丁,然后对master应用它?如果是这样,有什么方法可以保留一些历史记录吗?想法,建议等等。

s1ag04yj

s1ag04yj1#

您希望结合使用rerere-train.shrerere数据库的历史提交(您可能已经在/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时才需要学习功能。
附言。我找到了另一个问题的类似答案:https://stackoverflow.com/a/4155237/334451

s6fujrry

s6fujrry2#

您可以使用git rerere功能。
您必须使用git config --global rerere.enabled 1启用它,之后,您解决的每个冲突都会被存储起来供以后使用,并且解决方案会在相同的上下文中重新应用。
您可以使用git rerere diff检查存储的分辨率。
查看此tutorial了解更多信息。

wfveoks0

wfveoks03#

为什么不在初始交互式重定基中把冗余补丁放在一起(首先把它们重新排序,这样它们就在一起了),这样你就可以清除掉序列中的“先修改后删除”部分。在这个阶段,你可以选择提交中的块(例如使用git gui)。这会给予你一个更好的序列来完成最终的干净重定基。

8yparm6h

8yparm6h4#

(This这是我对这个问题的第二个回答。在第二次阅读时,我认为原来的问题可能与我第一次理解的问题有点不同。)
我理解这个问题,因为你有一个类似于master的开发分支,通常这种类型的分支风格被称为特性分支,我绝对鼓励使用它们。
你应该总是尝试保持feature分支干净。在实践中,你想要一个feature分支,如果你从来没有犯过任何错误,你会已经做了提交。对我来说,这意味着提交很多和后来的git rebase -i,以修复错误,当我后来了解到这些错误。
当特性分支准备就绪时,它应该如下所示
1.添加API以执行X操作
1.修正角箱Z的现有API Y
1.使用X和Y添加特征B(也适用于Z!)
1.改进功能B:变魔术
代替
1.在制品
1.擦拭巾2
1.添加API
1.移动API以执行X
1.添加功能B
1.重新考虑后,重命名X的参数
1.固定要素B
1.修复X的APi
1.固定角箱Z
1.也为API Y固定角箱Z
1.变魔术
1.提交丢失的文件
如果你将特性分支的基重定到最新的master分支,那么修改量很大,只有提交Fix existing API Y for corner case Z可能会导致冲突。如果该提交是修改 * 现有 * API的最小修改,那么修复冲突应该很容易。此外,只有当其他提交修改了你的最小修改所涉及的行时,才会出现冲突。
如果执行要素分支和要素分支重定基而不是合并(我更喜欢的风格是重新定基,这样就可以快进,然后执行git checkout master && git merge --no-ff feature-branch-x,并在合并提交中记录整个过程-这允许保留分支的完整历史,并允许GUI工具在需要时轻松导航该特性)在将这些分支重新定基到master之前,您肯定希望执行keep your feature branches clean。从长远来看,不仅你的重定基会更容易,而且历史记录也是可读的。(从技术上讲,这会产生一个新的提交,其内容在逻辑上与挤压合并相同,但它的第二个父提交将指向具有功能分支的整个历史的提交序列。喜欢挤压合并的人可以使用第一个父提交,喜欢具有历史的人可以使用第二个父提交。你可以在这个新提交中为假想的挤压合并提交编写提交消息。)
在上面的例子中,你可以使用rebase -i <old-enough-sha1>,然后将提交重新排序为3 + 4 + 6 + 8,10,1 + 2 + 5 + 7 + 9,11 + 12,其中+表示压缩。但通常更容易的做法是让提交量保持很小,然后在以后压缩其中的一些。注意,在这个例子中,即使是第10次提交也比第一次提交早,这是正常的,反映了你的实现并不完美,但这不需要保存在版本历史中。
就你而言,听起来你有一个特性分支,其中多次提交添加和删除相同的东西。2将这些提交压缩为一个单独的提交(可能最后没有变化,这没关系)。只有当特性分支看起来干净的时候,才把你的特性分支的基重定为master。一定要学会使用git gui或其他一些工具,使提交修改过的 * 行 * 而不是 * 文件 * 变得容易。每一次提交都应该是一次修改一个健全的东西集合的改变。如果你添加了一个新的特性X,同一次提交 * 一定不能 * 修复现有的函数Y或添加关于Z的缺失文档。即使这些改变是对同一个 * 文件 * 做出的。对我来说,这就是Linus Torvalds说"files do not matter"时所指的东西。

相关问题