git cherry-pick:手动接受冲突文件中的“我们的”或“他们的”帅哥

时间:2019-01-17 09:49:08

标签: git cherry-pick

我目前正在挑选一些提交到另一个(发布)分支的提交。我在选择樱桃时了解--strategy-option theirs,但恐怕此选项不适用于我选择的每个提交。

我更喜欢使用默认策略生成冲突,然后手动解决每个文件的冲突。

但是,有些文件我想批量接受所有ourstheir大块文件,而手工做起来很麻烦。 有没有办法只接受冲突文件中的所有ourstheir大块?

注意:git checkout --ours/--theirs似乎不适合进行挑选,因为它会从给定分支中检出整个文件。我只想接受任何一个版本中发生冲突的帅哥。

1 个答案:

答案 0 :(得分:1)

没有一种真正方便的方法来执行此操作,但是您可以从Git提供的工具中构建一个。所需的主要工具是此git merge-file,它对单个文件版本(即基础+我们的+他们的文件)进行三路合并。它接受--ours--theirs选项以解决冲突的方式与-X ours-X theirs进行整体合并的方式相同,即,它不仅仅使用我们的文件或它们的文件,它只会使我们或他们的文件位于冲突点。

那太好了,但是,您从哪里获得这三个版本? Git已停止,例如main.py发生合并冲突。在您的工作树中,main.py包含Git留下的混乱,在冲突的线周围带有<<<<<<< ... >>>>>>>标记。但是git merge-file需要三个未标记的输入文件,分别是合并基本版本,“我们的”版本和“他们的”版本。但是,这三个文件都在索引中!!如果文件 F 发生冲突,则有一个:1:F带有合并基础版本,:2:F带有和我们的:3:F

要获取它们,可以使用git showgit checkout-index。后者实际上是正确的工具:git mergetool使用git checkout-index,并具有以下shell函数:

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的阶段1(合并基础)副本提取到main.py.base中。重复2和3,以及第三个参数的合适变体,以获取所有三个文件。然后,按照the git merge-file documentation中所述的方式在三个文件上运行git merge-file

(有关更多信息,请参见the git mergetool source code。这只是一个很大的shell脚本,因此可以很容易地为自己的目的进行阅读和修改。)