我目前正在挑选一些提交到另一个(发布)分支中。我在挑选时知道--strategy-option theirs
,但恐怕这个选项不适合我挑选的每一个提交。
我更喜欢使用生成冲突的默认策略运行,然后手动解决每个文件的冲突。
然而,有些文件中我想批量接受所有ours
或their
大块,这会让手工操作变得很麻烦。有没有办法只接受冲突文件中的所有ours
或their
块?
注意:git checkout --ours/--theirs
似乎不适合樱桃采摘,因为它从给定的分支中检出整个文件。我只想接受两个版本中相互矛盾的大块头。
没有一种真正方便的方法可以做到这一点,但您可以从Git提供的工具中构建一种方法。所需的主要工具是这个git merge-file
,它对单个三个文件版本执行三方合并,即base+ours+their。它接受--ours
和--theirs
选项来解决冲突,就像-X ours
和-X theirs
对整体合并所做的那样,也就是说,它不仅接受我们的文件或他们的文件,它只在冲突点接受我们的或他们的。
这一切都很好,但是,你从哪里得到这三个版本?Git因main.py
上的合并冲突而停止。在您的工作树中,main.py
包含Git留下的混乱,<<<<<<< ... >>>>>>>
标记围绕着冲突的行。但是git merge-file
需要三个未标记的输入文件,用于合并基础版本、"我们的"版本和"他们的"版本。但是这三个文件在索引中如果文件F发生冲突,则存在与合并基础版本的:1:F
、与我们的:2:F
以及与他们的:3:F
。
要获取它们,您可以使用git show
或git checkout-index
。后者实际上是正确的工具:git mergetool
使用git checkout-index
,带有这个小外壳函数:
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 main.py main.py.base
,提取main.py
到main.py.base
的第1阶段(合并基础)副本。重复使用2和3,以及第三个参数的适当变体,以获得所有三个文件。然后,按照git merge-file
文档中描述的方式对这三个文件运行git merge-file
。
(更多信息请参阅git mergetool
源代码。这只是一个大的shell脚本,因此很容易阅读和修改。)