我正在编写一个自定义合并驱动程序,需要知道它正在合并的分支的名称。我设法检索了与git symbolic-ref HEAD
合并到(目标)的分支的名称,以及从GITHEAD_<SHA>
环境变量合并到(源)的分支的名称。
# retrieve merged branch name from an env var GITHEAD_<sha>=<branchName>
# we cannot use a sym ref of MERGE_HEAD, as it doesn't yet exist
gitHead=$(env | grep GITHEAD) # e.g. GITHEAD_<sha>=release/1.43
# cut out everything up to the last "=" sign
source="${gitHead##*=}"
# retrieve base branch name from a sym ref of HEAD
branch=$(git symbolic-ref HEAD) # e.g. refs/heads/master
# cut out "refs/heads"
destination="${branch#refs/heads/}"
echo "Merging from $source into $destination"
这是正确的做法吗?特别是,从环境变量中检索 source 名称似乎很不稳定。请注意,此时MERGE_HEAD不存在,因此我不能使用与HEAD相同的方法。
答案 0 :(得分:1)
是的,这与合并驱动程序中的距离非常接近。
合并策略通过查找每个GITHEAD_%s
获取正确的名称,其中每个%s
参数都从给定合并策略的参数中填充,每个“远程头”。有关详细信息,请参阅my answer to a related question。这在任何地方都没有记录,只是from the source。不幸的是,当您进入合并驱动程序时,this information is lost:没有%
指令可以检索这些名称,即使可能存在。 (添加一些%
指令应该很简单:只需增加字典的大小并添加适当的指令和strbuf
对象。)
如果你正在处理一个正常的双头和一个基础的合并,那么只有一个GITHEAD_*
变量而且它是另一个头,但如果你正在处理一个章鱼合并,那你就不走运了
答案 1 :(得分:0)
我已经处理了几周的任务,并且发现了一些脚本无法正确处理的极端情况。到处搜索并查看Git来源,我已经找到了这个脚本:
#!/bin/bash
# ${1} is the base common file
# ${2} is the file as modified by the base branch, and where the results must be
# ${3} is the file as modified by the incoming branch / stash
# ${4} is the path of the file being merged
# does not support octopus merge.
branch=$(git symbolic-ref --short HEAD || git name-rev --name-only HEAD)
githeadNum=$(env | grep GITHEAD | wc -l) # pathces do not create any GITHEAD var
# get a GITHEAD with message 'Stashed changes'
# if we are applying a stash, it must exist.
# see https://github.com/git/git/blob/2d08f3deb9feb73dc8d21d75bfd367839fc1322c/git-stash.sh#L616
stash=$(env | grep -E 'GITHEAD_[0-9a-f]{40}\b*=\b*Stashed changes' | wc -l) # e.g. GITHEAD_<sha>=Stashed changes
if [ "$stash" -eq "1" ]
then
# we are in a stash
else
if [ "$githeadNum" -eq "0" ]
then
# we are in a patch
else
# normal merge
# only one GITHEAD, merging
gitHeadName=$(env | grep GITHEAD)
source="${gitHeadName##*=}"
fi
fi
exit 1
我将目标分支恢复为
$(git symbolic-ref --short HEAD || git name-rev --name-only HEAD)
我发现第一部分失败了rebase
,因此如果需要重新设置基准,第二部分应该可以工作。
对于源代码,我解析了GITHEAD env变量,但检查了补丁程序或隐藏应用程序,因为我想以不同的方式处理这些情况(补丁程序不会离开GITHEAD)
适用于藏匿处:
stash=$(env | grep -E 'GITHEAD_[0-9a-f]{40}\b*=\b*Stashed changes' | wc -l)
如果我们处于隐藏状态,$ stash将为1,否则为0
对于补丁,我计算GITHEAD的数量,该数量必须为零:
githeadNum=$(env | grep GITHEAD | wc -l)