如果我使用 git checkout develop -- A,那将来会不会导致严重的合并冲突?
不,它本身不会。合并通过将每个提示与合并基础进行比较,然后比较两组更改来工作。如果两个分支都进行相同的更改,则没有冲突。
Other 任何一个分支上的更改,或者太接近两个分支上共同更改的行,都可能表现为冲突。阻止这些的方法是通过记录来自公共内容的合并,为 git 提供准确的合并基础。
# merging master and develop, but there are common changes and
# also changes that conflict only with those common changes.
# supply git's merge with the common changes as part of the base,
# so it will see that it needs to resolve only those other changes
# check out the current merge base
git checkout $(git merge-base master develop)
# make the changes you're merging
git checkout develop -- file_A
git commit -m "cherrypicking file_A as of develop @ $(git rev-parse develop)"
# (for ensuite)
base=$(git rev-parse HEAD)
# record that both branches have those changes
git checkout develop
git merge -s ours $base -m "recording common content from previous cherry-picks"
git checkout master
git merge -s ours $base -m "recording common content from previous cherry-picks"
# and now this merge will get an accurate base:
git merge develop
现在:这些 $base 合并的唯一效果是将公共内容记录为两个分支提示的祖先,从而为从 develop 到 master 的合并提供一个准确的基础,从而解决其他更改。
新的提交使历史与广泛使用的successful git branching model 中给出的做法保持一致。
如果就您的团队如何解释提交而言,最好只将常见内容的来源记录在提交消息的文本中,那么 git 也能做到这一点。除了永久记录祖先,通过上述base 分配后的结帐和合并,您还可以
echo $(git rev-parse master master~) $base > .git/info/grafts
echo $(git rev-parse develop develop~) $base >>.git/info/grafts
git checkout master
git merge develop
# later, whenever you want -- the ancestry above is strictly repo-local
rm .git/info/grafts
.git/info/grafts 中记录的祖先是 repo-local。您的合并命令会看到它,结果将是正确的。唯一的缺点是因为基地实际上并没有被记录下来,其他人在重复它时也会遇到同样的麻烦——除非你在做 criss-cross merges 或者还挑选其他分支,否则不太可能。