如何防止在rebase许多commit时发生许多git冲突?

zlwx9yxi  于 2023-05-12  发布在  Git
关注(0)|答案(6)|浏览(225)

故事:在一个项目中,我的同事从 master 创建了一个新的分支,并开始做她繁重的重构工作。我从 master 创建了我的分支,并开始在页面上做新的东西。我们定期提交,但只有我可以将代码变基到 master(因为同事的更改太多,还不能从master部署)。不幸的是,我们的一些工作依赖于相同的文件。所以在工作了几天后,当她最终想将她的更改重定向到 master 时,她遇到了很多git冲突。

my_branch    #---#----#-#-------#----#--#-----#---#----#----#
            /     \              \   \   \              \    \
master     *-------*--------------*---*---*--------------*----*----*
            \                                                     /
her branch   #------#-------#-----------#-----------#------------#

问题1为:如何防止在处理相同文件时发生大量的git冲突?(或者在这种情况下的最佳做法是什么?)
但这不是我们问题的结束,...为了绝对正确,她试图从master到她的分支进行rebase(以提交更改),因此提交Map应该看起来像这样

my_branch    #---#----#-#-------#----#--#-----#---#----#----#
            /     \              \   \   \              \    \
master     *-------*--------------*---*---*--------------*----*----*
            \                   \            \                    /
her branch   #------#-------#----*------#-----*-----#------------#

而这正是困扰我们的。在这些重建基地的过程中,她正在解决这些冲突。但是git不记得她对冲突修复的决定,所以当她从 masterher-branch 进行另一次git rebase时,她不得不再次修复她在以前的rebase中修复的相同的git冲突

问题2为:如何告诉git在 master 分支的git rebase后记住git冲突修复,这样在下一次rebase后我们就不必再次修复相同的冲突了?

egmofgnx

egmofgnx1#

幸运的是,git有一个专门处理这个问题的机制,叫做git rerere--本质上,如果你启用了git rerere,那么每次你解决一个冲突的时候,你以一种特定的方式解决了这个冲突的事实都会被记住。如果再次出现相同的冲突,则自动使用相同的解决方案。下面有一些有用的文章:

但实际上你可以这样做:

git config --global rerere.enabled 1

...忘记它,同时享受更容易的rebase/ merging:)

hrysbysz

hrysbysz2#

让我来分享一种解决变基冲突的可能方法。我称之为rebase via merge。如果你想对一个有很多提交和很多冲突的分支进行变基,它会很有帮助。
首先,让我们创建一个temp分支,并通过常规合并强制显示所有冲突

git checkout -b temp
git merge origin/master

按常规方式解决所有冲突并完成合并。
因此,temp分支现在显示了正确解决所有冲突后项目的外观。
现在,让我们 checkout 未修改的分支(假设它是alpha)。

git checkout alpha

并使用机械冲突自动解决方法进行重定基,以支持当前分支。

git rebase origin/master -X theirs

项目代码此时可能已损坏或无效。很好,最后一步是通过一次额外的提交从temp分支恢复项目状态

git merge --ff $(git commit-tree temp^{tree} -m "Fix after rebase" -p HEAD)

基本上,这一步使用一个低级的git命令来创建一个与temp分支中完全相同的项目状态(树)的新提交。新提交将立即合并。
就这样。我们通过隐藏合并做了一个变基。和temp分支可以删除。

git branch -D temp

此外,还有一个脚本可以交互地做同样的事情。可以找到**here**。

pgvzfuti

pgvzfuti3#

请确保始终使用--onto开关进行变基。
若要防止冲突,请使用浮动开发分支。每个开发人员都将不断地重定其开发分支的基。这很容易,因为开发人员知道他刚刚实现了什么,并且在解决冲突方面不应该有问题。而不是rebase,只是合并最终版本(它已经被rebase)。

3pvhb19x

3pvhb19x4#

您可以压缩她的分支以防止连续冲突解决。当你在从master创建后将她分支中所有的commit压缩成一个commit时,冲突可以一步解决。
如果你想从头开始写新的提交消息,这就足够了:

git reset --soft HEAD~3 &&
git commit

在这个例子中,我们将压缩最后3个提交。
为了防止将来出现这个问题,我建议你在每次提交后用源分支来重定你的分支的基。

tgabmvqs

tgabmvqs5#

如果两个开发者对同一行代码做了不同的修改,冲突将是不可避免的,因为git不知道应该保留或丢弃哪个。
至于从master中变基,这真的不是理想的实践,除非你想故意改变提交历史(可能还想改变同事的提交历史)。
来自官方文档about rebasing
不要重新设置存在于存储库之外的提交,并且人们可能基于这些提交进行工作。
您应该使用git merge

ovfsdjhp

ovfsdjhp6#

除了简单的用例之外,我不再使用rebase。cherry-pick几乎总是更容易使用,并且需要更简单的心理模型。cherry-pick最复杂的事情是,有时你需要创建一个新的干净分支,并在那里应用cherry-pick提交。

相关问题