Git 如何配置合并策略?
我想用不同的配置文件合并两个分支,这样即使没有冲突,配置文件也保持不变。正如我从和中了解到的,我需要配置自定义合并策略而不是合并驱动程序(我已经配置了合并驱动程序,并且在发生冲突合并时工作正常) 我正试图在公司的指导下制定我的合并战略 我在我的项目根目录(my.gittributes所在的位置)中创建了git-merge-mystrategy.sh,其中包含以下代码:Git 如何配置合并策略?,git,merge,Git,Merge,我想用不同的配置文件合并两个分支,这样即使没有冲突,配置文件也保持不变。正如我从和中了解到的,我需要配置自定义合并策略而不是合并驱动程序(我已经配置了合并驱动程序,并且在发生冲突合并时工作正常) 我正试图在公司的指导下制定我的合并战略 我在我的项目根目录(my.gittributes所在的位置)中创建了git-merge-mystrategy.sh,其中包含以下代码: merge-file -q --ours "$2" "$1" "$3"; 在.git属性中,我有: pom.xml merge
merge-file -q --ours "$2" "$1" "$3";
在.git属性中,我有:
pom.xml merge=ours
当我跑步时:
git merge --strategy mystrategy develop
我得到:
Could not find merge strategy 'mystrategy'.
Available strategies are: octopus ours recursive resolve subtree.
我可能缺少这一部分:在路径中创建一个可执行的git merge mystrategy
你能给我一些关于如何创建自定义合并策略的详细信息吗?正如你所猜测的,你必须把git merge mystrategy.sh
放入一个文件中,git可以通过$PATH
找到该文件。该文件必须是可执行文件(chmod+x
在Unix/Linux上,我不知道在Windows上是什么),如果您以git merge-s mystrategy
运行它,则必须通过名称git merge mystrategy
找到该文件。(您可以运行git merge-s mystrategy.sh
来搜索git merge mystrategy.sh的$PATH
)
更大的问题是,编写正确的合并策略并不容易。这:
这是行不通的。您的策略将使用由git merge
计算的特定参数调用,但没有一个是文件名。我将在这里用一个非功能性的合并策略脚本来说明这一点
如果您运行:
git merge --strategy mystrategy develop
git merge -s mystrategy -Xa -Xkcd=12 --find-renames=35 develop
将使用四个(!)参数调用脚本。如果您运行:
git merge --strategy mystrategy develop
git merge -s mystrategy -Xa -Xkcd=12 --find-renames=35 develop
您的脚本将获得七个参数:
$ cat ~/scripts/git-merge-silly
#! /bin/sh
echo "I got $# arguments..."
for i do
printf "%s\n" "$i"
done
read junk
$ chmod +x ~/scripts/git-merge-silly
$ git merge -s silly -Xa -Xkcd=12 -X find-renames=35 b1
I got 7 arguments...
--a
--kcd=12
--find-renames=35
4f95ecf496de9dfe175e7ed4dd97972adf0ca625
--
HEAD
439e327bc8f8e78d74b27ae89f433451eec09111
(此时脚本正在从stdin读取变量junk
,因此所有内容都会暂停,我可以按CTRL+C来中断它并停止伪合并)
以下是论点的内容及其含义:
--whatever
:这将通过一个扩展策略选项,-X whatever
。如您所见,这些参数没有经过审查:它们实际上只是任意字符串(-Xkcd
选项的含义是什么?)
- 在
--
之前的散列,或者在某些情况下是多个散列:这是要合并的头的合并基,如果有多个合并基,则为合并基
--
:这将合并基与指定要合并的头的字符串分开
HEAD
:这始终是下一个参数;它被编译成git merge
。这是本地头,对于像-s ours
(或-s theres
,如果存在)这样的策略,它有一点额外的意义,但对于大多数合并策略,您应该将其视为剩余参数
- 一个或多个散列ID:Git称之为要合并的远程头。在这种情况下,运行
git merge。。。develope
,Git已将develope
解析为一个特定的提交ID,该ID是名为develope
的分支的tip提交,该提交是远程头
作为合并策略,您现在的工作是:
- 查找自合并基站以来对各个磁头(磁头加上每个遥控器)的更改
- 合并这些更改,将生成的合并文件写入索引树和工作树
- 退出时,状态指示您的成功或失败状态
也许最简单的说法是:
在这一点上,我们需要一个真正的合并。不管采取什么策略
我们使用,它会对索引进行操作,可能会影响
工作树,当清晰地解析时,具有所需的
索引中的树——这意味着索引必须位于
与头部同步提交。这些战略是负责任的
为了确保这一点
而且,:
当发生冲突时,后端将以1退出
留待解决,不解决时为2
处理给定的合并
如果在命令行上提供多个-s
选项,git merge
code将(在现代git中)为您运行git stash
,然后在每次策略尝试之间执行git reset--hard
和git stash apply
,直到其中一个以0状态退出而完全成功,在这种情况下Git接受其结果,或者它用尽了尝试的策略。策略用完后,如果其中一些退出1而不是2,Git会选择产生“最佳”结果的策略,其中“最佳”是一个有点奇怪的度量:更改的文件(相对于头提交)和未合并的文件的最小数值总和被认为是“最佳”结果。(在我看来,可能未合并的文件在这里应该有更重的权重。)在再次硬重置之后,它将重新运行最佳合并
无论如何,所有这些的要点是,在合并策略中,您有很多工作要做。在继续之前,最好确保索引和工作树处于合理的可恢复状态,如果没有,最好拒绝合并(使用“请提交或隐藏您的更改”)。类似地,如果存在多个合并基,可以使用退出2
完全拒绝尝试,否则必须对多个合并基采取措施。(解析
策略选择其中一个,忽略其余的,这是一个有效的选项,但并不总是最好的选项。递归
策略合并合并基,并使用结果提交作为新的合并基。)
然后,对于每个头部,您自己的常规头部
头部加上每个远程头部,您必须找到更改。通常的递归和解析策略拒绝运行,除非正好有两个头,运行git diff
,默认情况下重命名检测设置为50%,允许-X
参数