如何处理具有许多冲突且不能最好由同一个人处理的大型合并?

Jos*_*eph 7 git

假设我们有一个develop分支和一个feature分支。该develop分支非常频繁地收到来自数十名开发人员的许多更新。它经常比分支走得更远feature

有一次,from 的合并develop导致feature了 300 个低级冲突。这些冲突涉及代码库的许多不同领域,并且没有一个开发人员熟悉所有这些领域。因此,任何单个开发人员都很难解决其本地计算机上的每个冲突,以便推送逻辑正确、无冲突的项目版本。

我知道最好的解决办法是避免这种情况。然而,排除——由于组织功能失调、既成事实等原因,这种情况存在——如何最好地利用git来解脱呢?

我对 git 的理解是,不可能提交任何处于冲突状态的东西;通过分阶段,您表明它并不冲突。然而,这似乎要求任何和所有冲突都成为进行合并的人的不共享、不协作的责任。这是不可取的,因为解决冲突是一项艰巨的任务,各个部分最好由不同的人处理。

我想到了两种可能的出路。然而,两者听起来都不是很好。首先,我考虑尝试解决我能解决的冲突,仅提交这些解决方案,然后让其他开发人员处理他们适合的部分。然而,据我所知,git 不支持任何类型的临时合并提交,并且实际上不会让您开始合并并随后提交,除非您在本地处理add每个冲突的文件,从而将其标记为已解决。我相信这个答案支持了我的担忧。

这让我想到了第二个想法,那就是仅仅修复我能修复的部分,并提交其余的部分,包括冲突标记。幸运的是,我能够解决所有高级冲突(文件重命名/删除等),但如果我没有解决,这些仍然是一个问题。抛开feature分支将处于非编译状态不谈,我担心 git 将不再认为这些文件存在冲突;这意味着我们必须依赖 IDE 和其他工具来检测 git 冲突标记。

我的偏好是仅提交实际已解决的文件,允许其他开发人员拉取它们,而未实际解决的文件仍向他们指示为冲突。

我还注意到有一个--no-commit可用的选项git merge,我想知道这是否是可行的方法,因为我认为它允许我只提交我实际审查过、理解和解决的文件,同时保留剩余的文件本地未提交的冲突。

是否有更有效的策略来使用 git 将合并的责任分配给多个开发人员?

eft*_*ft0 11

有一些方法可以应对它......但它们并不美丽。比如说,合并到一个单独的分支上,该分支将用于......比方说,稳定它......保留冲突文件的列表。提交有冲突的结果(糟糕,我知道......最终会有意义,继续阅读)。现在让开发人员在分支上工作来解决冲突(提供文件列表,分配谁将处理什么等等)....继续在该分支上工作(如果有必要,可以使用拉取请求) ....正常的开发流程...好吧,合并冲突解决中的正常情况

当它最终稳定下来,所有冲突都解决了等等(这就是 git 的美妙之处),只需压缩所有用于稳定它的修订并修改合并修订,使其看起来没有稳定过程......它就会看起来你只是简单地合并,不需要任何稳定。所以...类似:

git checkout -b stabilize main
git merge the-other-branch
# you get a gazillion conflicts....
git status > status_merge.txt # keep the list of stuff
git add .
git commit -m "Merging with conflicts.... this is not finished"
# let's set a temporary branch on this revision, so that it is easier to go into the final steps
git branch broken-merge
git push the-remote stabilize
Run Code Online (Sandbox Code Playgroud)

现在传递要处理的文件列表,让您的开发人员在该分支之上享受乐趣,直到它最终得到解决......当它得到解决时,您可以回来总结它:

git fetch the-remote
git checkout the-remote/stabilize
git reset --soft broken-merge # this is your magic wand in action
# now, all the changes that developers had to do to stabilize the branch are in index
git commit --amend -m "Real merge, stabilized"
# and now you have the _real_ results of the merge _replacing_ the old completely broken revision, like it never happened... and you get the credit for it :-)
git branch -f main # let's set main over here... this assumes that main hasn't moved since stabilization started
git push the-remote main
# take a bow
Run Code Online (Sandbox Code Playgroud)

就是这样。我同意,这不是最优雅的......但它会起作用。

如果您想保留用于稳定分支的工作,我建议使用管道命令创建一个新的修订版,该命令允许我们凭空创建它们,因此将配方的第二部分替换为拿来:

git fetch the-remote
git branch temp $( git commit-tree -p main -p the-other-branch -p the-remote/stabilize -m "Merging main and the-feature-branch" the-remote/stabilize^{tree} )
# commit-tree is the plumbing command that creates revisions at will. 
# That command will spit out a revision ID that, thanks to $( )
# we use as input to git branch temp to tell git on what revision
# we want temp to be.
#
# Said revision has main, the-feature-branch _and_
# the-remote/stabilize as parents _and_ has the tree
# (files/contents) of the-remote/stabilize, which is
# the final result of the merge.
#
# if you like how it looks/feels, let's put main over here
git checkout main
git merge temp # this should do a ff to that revision we created
# we can now delete temp
git branch -d temp
git push the-remote main
Run Code Online (Sandbox Code Playgroud)

作为最后的细节,这假设主/功能分支在稳定发生时不会移动......如果情况并非如此(分支确实移动),那么您需要更多的工作才能获得对的。

稳定发生时,分支(主分支、功能分支)确实会移动

第一个食谱的第二部分中,它的工作原理如下:

git fetch the-remote
git checkout the-remote/stabilize
git reset --soft broken-merge # this is your magic wand in action
# now, all the changes that developers had to do to stabilize the branch are in index
git commit --amend -m "Real merge, stabilized"
git branch temp
# and now you have the _real_ results of the merge _replacing_ the old completely broken revision, like it never happened... and you get the credit for it :-)
# unfortunately main has moved, so we need to _merge_ this into main
git checkout main
git merge the-remote/main # or pull... but we have already fetched recently, right? so no _real_ need to pull
git merge temp # merge the stabilized result of the merge between main and the-feature-branch started back in time
# you might get conflicts coming from the work that was introduced in main after the point where we started to stabilize
# assuming that the merge is finished:
git push the-remote main
# we can now delete temp
git branch -d temp
# take a bow
Run Code Online (Sandbox Code Playgroud)

如果您采用第二个建议(将稳定工作保留在历史中),则方案的第二部分将变为:

git checkout main
git pull # get the contents of main and the new position of the stabilization branch (that is finished, right?)
git branch temp $( git commit-tree -p broken-merge^ -p broken-merge^2 -p the-remote/stabilize -m "Merging main and the-feature-branch" the-remote/stabilize^{tree} )
# just like the previous commit-tree with the recipe with
# main/the-feature-branch not moving _but_ using the
# old positions of main/the-feature-branch as parents
git merge temp # merge back into main.... could get conflicts because of the things that have gone into main since we started to stabilize
# we can now delete temp
git branch -d temp
git push the-remote main
Run Code Online (Sandbox Code Playgroud)

  • 我同意……我并没有说这是卢浮宫的东西。 (2认同)