第一:
git merge origin/remote_branch
应该阅读git merge --no-commit 以确保如果没有合并冲突,Git 不会提交这些更改,否则您的下一步将没有多大意义。请注意,如果--theirs 提交更改了一些pom.xml 文件而您没有更改它们,或者Git 认为它成功合并了您和他们的更改,则根本不会有合并冲突。 (如果你想在其中一种情况下使用他们的,那也有点棘手,但你似乎总是想使用--ours 版本。)
下一步:
git checkout --ours **/pom.xml pom.xml
这依赖于你的 shell(大概是 bash 或类似的)以你想要的方式扩展 **;您可能想引用星号,并让 Git 进行全局扩展。不过,这可能会影响您的特定情况,而且我不确定 Git 在合并冲突期间如何处理此问题,因此在您执行此类操作之前,您需要仔细试验。
这很好用,除非在本地分支中删除了 pom.xml 文件。运行上面的命令 #2 后,我们得到一个错误:
d:\code>git checkout --ours **/pom.xml pom.xml
error: path 'blah/pom.xml' does not have our version
正确:对于这种情况,如果您想保留已删除的文件,您需要覆盖 Git 的默认操作,即选择将其版本保留在索引和工作树中。
让我们跳到所有这一切的特定于 Git 的部分,即 index。请记住,Git 的索引是您构建 next 提交的位置。在合并期间,它也是您解决冲突的地方。
合并期间索引中的条目
在正常(非合并)情况下,索引对每个跟踪的文件都有一个条目。如果文件 F 在当前 (HEAD) 提交和工作树中,则索引具有 F 的条目。最初,此索引条目版本与 HEAD 版本匹配。您修改工作树中的文件,然后git add 工作树版本将其复制到索引中,而不是 HEAD 版本;然后下一个git commit 将保存索引版本。
在冲突合并期间,当文件 F 发生冲突时,索引有 最多三个 的 F 条目,而不是通常的一个.这些条目位于插槽号 1、2 和 3 中。(插槽 0 为正常的、不冲突的条目保留。)插槽 1 用于 merge base 版本。插槽 2 用于--ours,插槽 3 用于--theirs,您可以将这些名称用于 2 和 3,但插槽 1 没有名称。
在以下情况下发生合并冲突:
- 在我们和他们的版本中修改了相同的行,相对于基本版本(这是修改/修改冲突),或者
- 没有基础版本,只有我们和他们的(这是创建/创建冲突),或者
- 我们删除了文件,他们更改了一些内容,甚至只是名称(这是删除/修改或删除/重命名冲突),或者
- 他们删除了文件,我们更改了一些内容:这也是修改/删除或重命名/删除冲突,合作伙伴互换了。
对于修改/修改冲突,所有三个插槽都已填充。对于其他三种冲突,一个槽为空:合并基槽为空(创建/创建),或--ours为空(删除/X),或--theirs为空(X/删除)。
当--ours 插槽为空时,git checkout --ours 步骤将失败。当--ours 槽不为空时,它会成功:它将--ours 版本提取到工作树中。
Git 对任何 delete/X 或 X/delete 冲突的默认操作是留在工作树中,无论哪个版本幸存。也就是说,如果插槽 3(他们的)为空,则工作树文件匹配插槽 2 条目,但如果插槽 2(我们的)为空,则工作树文件匹配插槽 3 条目。
您可以选择通过扫描空的“slot 2”和git rming 文件来处理这种情况:
git ls-files --stage | fancy-script-or-program
如果您将其编写为 Python 程序,请使用 git ls-files -z --stage 使其易于机器解析。您甚至可以完全停止使用git checkout --ours,并停止依赖shell 或Git globbing,并完全在脚本中编写解析pom.xml 文件的规则。
基本上,您可能会通读整个索引,查找其基本名称(最后一个 / 之后的所有内容)与 pom.xml 匹配的文件:
如果有零阶段条目,Git 认为它正确解析了文件。将哈希 ID 与 HEAD 提交中的 ID 进行比较,因为 Git 可能实际上并没有正确解析文件;在这种情况下,将索引 blob 散列替换为来自 HEAD 提交的散列。有关详细信息,请参阅the git update-index documentation。你应该可以使用--cacheinfo,尽管我没有使用未合并的索引条目对此进行测试。
否则,有阶段 1、2 和/或 3 条目。如果有第 2 阶段条目,则将其用作分辨率,即如上所述将其提供给git update-index。如果没有第 2 阶段条目,请使用git update-index 来删除这些条目(使用0 表示模式,以及任何内容,包括全零散列,用于哈希值;如果模式为 0,则哈希值无关。
一旦您对所有pom.xml 路径执行此操作,任何剩余的非零阶段索引条目都表明您应该将合并冲突传递回您的用户。否则,您可能已准备好提交。
(对http://gitpython.readthedocs.io/en/stable/reference.html#module-git.index.base 的快速浏览表明这可以在 GitPython 中相当容易地完成,但我没有使用它的经验。)
最后的警告:我完全没有使用 Maven 的经验,但我认为 pom.xml 文件是控制各种事物的 XML 文件,并且 Git 的合并很差(最后一点对于几乎所有 XML 文件都是如此)。不过,我完全不清楚仅使用“我们的”版本是否正确。