如何防止许多 git 冲突时,重新基于许多提交?

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

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

问题1是 : 当我们处理相同的文件时,如何防止大量的 git 冲突?(或者在这种情况下的最佳实践是什么?)

但是这并不是我们问题的结尾 ,... 为了绝对正确,她尝试从 master 到她的分支进行 rebase 操作(使我提交的更改得以实现) ,因此提交映射应该类似于下面这样

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

这就是困扰我们的问题。在这些重新部署期间,她一直在处理那些冲突。但是 Git 不记得她关于冲突修复的决定,所以当她做另一个从 师父她的树枝的 Git 重定位时,她不得不对 再次修复同样的 git 冲突重定位,这是她在以前的重定位中所做的。

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

23751 次浏览

幸运的是,git 有一个处理这个问题的机制叫做 git rerere——实际上,如果你启用了 git rerere,那么每次你解决一个冲突的时候,你以一种特殊的方式解决了这个冲突的事实就会被记住。如果再次出现相同的冲突,则自动使用相同的分辨率。以下是一些有用的文章:

但基本上你可以这样做:

git config --global rerere.enabled 1

... 忘记它,同时享受更容易的重新基础/合并:)

确保您总是使用 --onto开关重新定基。

若要防止冲突,请使用浮动开发分支。每个开发人员将不断地重新设置他们的开发分支的基础。这很容易,因为开发人员知道他刚刚实现了什么,并且不应该存在解决冲突的问题。只合并最终版本(它将已经重新基础) ,而不是重新基础。

你可以捏碎她的树枝,以防止连续的冲突解决。当您将所有提交从主创建到一个提交后压缩到她的分支中时,那么冲突可以一步解决。

如果您想从头开始编写新的提交消息,这就足够了:

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

在本例中,我们将压缩最后3次提交。

为了防止将来出现这种问题,我建议您在每次提交后使用源分支重新设置分支的基础。

让我来分享一种解决重定基冲突的可能方法。我叫它 通过合并重新定位。如果您希望对具有许多提交且预期会有许多冲突的分支进行重新基础化,那么它可能会有所帮助。

首先,让我们创建一个 temp分支,并强制使用常规合并显示所有冲突

git checkout -b temp
git merge origin/master

以常规方式解决所有冲突,完成合并。

因此,temp分支现在显示了正确解决所有冲突后项目应该是什么样子。

现在让我们检查一下您未触及的分支(让它是 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

此外,还有一个脚本可以交互式地执行同样的操作,可以找到 翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳

如果两个开发人员对同一行代码进行了不同的更改,冲突将是不可避免的,因为 git 不知道应该保留或放弃哪些内容。

至于从 master 进行 rebase,这确实不是理想的做法,除非您想要故意更改提交历史(并且可能更改您同事的提交历史)。

根据官方文件 重新定位:

不要对存在于存储库之外并且人们可能已经基于此进行了工作的提交进行重新建基。

您应该改用 git merge

enter image description here