如何在自定义Git合并驱动程序中检索分支名称? [英] How to retrieve branch names in a custom Git merge driver?
问题描述
我正在编写一个自定义合并驱动程序,该驱动程序需要知道它正在合并的分支的名称.我设法从GITHEAD_<SHA>
环境变量中检索了要与git symbolic-ref HEAD
合并到(目的地)的分支的名称,以及要在(源)中合并到(源)的分支的名称.
I'm writing a custom merge driver that needs to be aware of the names of the branches it is merging. I managed to retrieve the name of the branch being merged into (destination) with git symbolic-ref HEAD
and the name of the branch being merged in (source) from the GITHEAD_<SHA>
environment variable.
# 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相同的方法.
Is this the right way of doing this? Particularly, retrieving the source name from an environment variable seems flaky. Note that MERGE_HEAD is not present at this point, so I cannot use the same approach as with HEAD.
推荐答案
我已经处理了几周的任务,并且发现了一些无法通过此脚本正确处理的特殊情况.到处搜索并查看Git的源代码,我已经找到了这个脚本:
I have been handling this task for a few weeks and I have found a few corner cases that are not correctly handled by this script. Searching around and taking a look at Git sources I have arrived at this script:
#!/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
,因此,如果需要重新设置基础,第二部分应该可以工作.
I found the first part failing for rebase
, so in case of a rebase the second part should work.
对于源代码,我解析了GITHEAD env变量,但检查了补丁程序或隐藏应用程序,因为我想以不同的方式处理这些情况(补丁程序不会离开GITHEAD)
For the source, I parse the GITHEAD env variable but check for patches or stash application, since I want to handle those cases differently (and patches do not leave GITHEAD)
适用于藏匿处:
stash=$(env | grep -E 'GITHEAD_[0-9a-f]{40}\b*=\b*Stashed changes' | wc -l)
如果我们处于隐藏状态,$ stash将为1,否则为0
$stash will be 1 in case we are in a stash, 0 otherwhise
对于补丁,我计算了GITHEAD的数量,该数量必须为零:
For patches I count number of GITHEAD, which must be zero:
githeadNum=$(env | grep GITHEAD | wc -l)
这篇关于如何在自定义Git合并驱动程序中检索分支名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!