如何在自定义Git合并驱动程序中检索分支名称? [英] How to retrieve branch names in a custom Git merge driver?

查看:90
本文介绍了如何在自定义Git合并驱动程序中检索分支名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个自定义合并驱动程序,该驱动程序需要知道它正在合并的分支的名称.我设法从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆