git: 使用策略解决合并冲突
git: Resolve merge conflicts using strategy
场景:
尝试从分支 feature
合并到 master
见证小冲突,例如不同的版本号,不应合并
如何告诉 git 只合并不冲突的部分,不要触及冲突的部分,就像 运行ning git merge -s recursive -Xours feature
?
我目前的解决方案是运行git merge --abort
,然后是上面提到的策略-合并。有没有办法在不先中止我的合并的情况下做到这一点?我不想启动另一个工具或逐个解决每个冲突。
git docs on merging nor this SO thread都没有给任何建议。
您仍然需要一个接一个地完成每个 文件,但是您可以使用 git merge-file
来实现您想要的。您可能希望编写脚本来完成以下步骤。
当 Git 因合并冲突而停止时,Git 将冲突文件的 所有三个 版本留在索引/临时区域中。例如,假设冲突文件名为 README.txt
。然后因为有冲突,你的工作树中有一个 README.txt
带有冲突标记,但你也有:
:1:README.txt
:来自合并基础的 README.txt
(当前提交和合并目标提交都从中分离的公共提交)。
:2:README.txt
:来自 HEAD
或 --ours
提交的 README.txt
。
:3:README.txt
:来自 --theirs
提交的 README.txt
。
您可以将这三个文件中的每一个解压缩到一个临时文件中。例如,最直接的方法是使用 git show :1:README.txt > README.txt.base
。有一种更适合脚本编写的更奇特的方式——git mergetool
命令使用这个:
checkout_staged_file () {
tmpfile=$(expr \
"$(git checkout-index --temp --stage="" "" 2>/dev/null)" \
: '\([^ ]*\) ')
if test $? -eq 0 && test -n "$tmpfile"
then
mv -- "$(git rev-parse --show-cdup)$tmpfile" ""
else
>""
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>
.
中解决冲突有利于 "ours"
因此,考虑到以上所有情况,如果文件名为 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
的合并现已完成。对您希望应用此 "override conflicts from --ours
" 规则的所有其他文件重复这六个步骤。
场景:
尝试从分支
feature
合并到master
见证小冲突,例如不同的版本号,不应合并
如何告诉 git 只合并不冲突的部分,不要触及冲突的部分,就像 运行ning git merge -s recursive -Xours feature
?
我目前的解决方案是运行git merge --abort
,然后是上面提到的策略-合并。有没有办法在不先中止我的合并的情况下做到这一点?我不想启动另一个工具或逐个解决每个冲突。
git docs on merging nor this SO thread都没有给任何建议。
您仍然需要一个接一个地完成每个 文件,但是您可以使用 git merge-file
来实现您想要的。您可能希望编写脚本来完成以下步骤。
当 Git 因合并冲突而停止时,Git 将冲突文件的 所有三个 版本留在索引/临时区域中。例如,假设冲突文件名为 README.txt
。然后因为有冲突,你的工作树中有一个 README.txt
带有冲突标记,但你也有:
:1:README.txt
:来自合并基础的README.txt
(当前提交和合并目标提交都从中分离的公共提交)。:2:README.txt
:来自HEAD
或--ours
提交的README.txt
。:3:README.txt
:来自--theirs
提交的README.txt
。
您可以将这三个文件中的每一个解压缩到一个临时文件中。例如,最直接的方法是使用 git show :1:README.txt > README.txt.base
。有一种更适合脚本编写的更奇特的方式——git mergetool
命令使用这个:
checkout_staged_file () {
tmpfile=$(expr \
"$(git checkout-index --temp --stage="" "" 2>/dev/null)" \
: '\([^ ]*\) ')
if test $? -eq 0 && test -n "$tmpfile"
then
mv -- "$(git rev-parse --show-cdup)$tmpfile" ""
else
>""
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
的合并现已完成。对您希望应用此 "override conflicts from --ours
" 规则的所有其他文件重复这六个步骤。