git:使用策略解决合并冲突

时间:2018-07-03 09:07:05

标签: git merge git-merge

场景:

  1. 尝试从分支feature合并到master

  2. 证人轻微冲突,例如一个不同的版本号,不应合并

如何像运行git merge -s recursive -Xours feature时一样告诉git只合并不冲突的部分而不接触冲突的部分?

我当前的解决方案是运行git merge --abort,然后运行上述策略合并。有没有一种方法,而无需先中止我的合并?我不想启动另一个工具,也不想一个个地解决所有冲突。

git docs on merging和此SO thread均未提供任何建议。

1 个答案:

答案 0 :(得分:0)

您仍然必须逐一处理每个文件,但是您可以使用git merge-file来实现所需的功能。您可能希望编写一个脚本来完成以下步骤。

当Git因合并冲突而停止时,Git会将冲突文件的所有三个版本保留在索引/暂存区域中。例如,假设冲突文件名为README.txt。然后,因为发生了冲突,您的工作树中会有一个带有冲突标记的README.txt,但是您也有:

  • :1:README.txt:来自合并基础的README.txt(您当前的提交和合并目标的提交都偏离的通用提交)。
  • :2:README.txt:来自README.txtHEAD提交的--ours
  • :3:README.txt:来自README.txt提交的--theirs

您可以将这三个文件中的每一个解压缩到一个临时文件中。例如,最直接的方法是使用git show :1:README.txt > README.txt.base。有一种更合适的脚本编写方法— git mergetool命令使用以下方法:

checkout_staged_file () {
        tmpfile=$(expr \
                "$(git checkout-index --temp --stage="$1" "$2" 2>/dev/null)" \
                : '\([^ ]*\)    ')

        if test $? -eq 0 && test -n "$tmpfile"
        then
                mv -- "$(git rev-parse --show-cdup)$tmpfile" "$3"
        else
                >"$3"
        fi
}

其调用方式为:

    checkout_staged_file 1 "$MERGED" "$BASE"
    checkout_staged_file 2 "$MERGED" "$LOCAL"
    checkout_staged_file 3 "$MERGED" "$REMOTE"

无论如何,您的工作是提取这三个文件,然后运行:

git merge-file --ours <stage-2-file> <stage-1-file> <stage-3-file>

这将保留合并结果,并在<stage-2-file>中保留有利于“我们的”的冲突。

因此,鉴于上述所有情况,如果文件名为README.txt,而您想重新合并该文件的 ,其等效项为-X ours,这些将起作用(尽管git show方法不遵循CRLF设置,因此您可能需要更高级的git checkout-index东西):

git show :1:README.txt > README.txt.base
git checkout --ours README.txt
git show :3:README.txt > README.txt.other
git merge-file README.txt README.txt.base README.txt.other
rm README.txt.base README.txt.other
git add README.txt

README.txt的合并现已完成。对于您要为其应用此“与--ours覆盖冲突”规则的所有其他文件,重复上述六个步骤。