给定git refname,我可以检测它是散列,标记还是分支?

时间:2013-08-14 03:12:20

标签: git

我正在编写一个脚本,该脚本将采用用作创建分支的基础的规范。因此,它会有这样的东西:

git checkout -b $newbranch $startingpoint

现在,startingpoint可以指定为分支名称,标记或SHA1。

稍后在脚本中,我需要根据实际startingpoint的内容做不同的事情。曾经有人认为git rev-parse会给我这些信息,但我似乎无法屈服于我的心血来潮。

有没有git方式,最好是瓷器,以获取我寻求的信息?

更新

我使用show-ref信息来制作以下shell函数:

git_ref_type() {
    [ -n "$1" ] || die "Missing ref name"

    if git show-ref -q --verify "refs/heads/$1" 2>/dev/null; then
        echo "branch"
    elif git show-ref -q --verify "refs/tags/$1" 2>/dev/null; then
        echo "tag"
    elif git show-ref -q --verify "refs/remote/$1" 2>/dev/null; then
        echo "remote"
    elif git rev-parse --verify "$1^{commit}" >/dev/null 2>&1; then
        echo "hash"
    else
        echo "unknown"
    fi
    return 0
}

这似乎现在效果很好,但它只是经过了非常轻微的测试。

2 个答案:

答案 0 :(得分:15)

您可以使用show-ref命令(主要)执行您想要的操作。给定一些字符串,如果它引用了标签,那么......

git show-ref --verify refs/tags/$thestring

......将是真的。如果它是分支名称,那么......

git show-ref --verify refs/heads/$thestring

......将是真的。如果字符串失败了那两个测试,那么......

git rev-parse --verify "$thestring^{commit}"

...会告诉你它是否引用了一个提交(可能是一个完整的SHA1,一个部分SHA1,HEAD,或者可能是其他不属于前两个类别的东西。< / p>

答案 1 :(得分:6)

请注意,git 1.8.5 or 1.9 (Q4 2013)将提供一种新方法来测试ref是否为标记。

  

让“foo^{tag}”将标签剥离给自己,即无操作,如果“foo”不是标签,则会失败。

如何测试revision是一个标签? (或“检查git名称是否为标签”?)

git rev-parse --verify v1.0^{tag}

test $(git cat-file -t v1.0) = tag“更方便。

通过75aa26d

查看提交abdb54a1dRichard Hansen

peel_onion():添加对<rev>^{tag}

的支持
  

通过<rev>^{<type>}解除引用<rev>^{tag}完成<rev>系列对象描述符,直到找到标记对象(如果无法找到则失败)。

     

乍一看,这可能看起来不太有用,因为提交,树木和斑点不能剥到标签上,而标签只会剥离自己。
  但是,这可用于确保<rev>命名标记对象:

$ git rev-parse --verify v1.8.4^{tag}
04f013d
$ git rev-parse --verify master^{tag}
error: master^{tag}: expected tag type, but the object dereferences to tree type
fatal: Needed a single revision
  

用户可以通过检查“<rev>”的输出来确保git cat-file -t <rev>是标记对象,但是:

     
      
  • 鉴于<rev>^{tag}<rev>^{commit}<rev>^{tree}都存在,用户可能会<rev>^{blob}存在
  •   
  • 这种语法在某些情况下更方便/更自然
  •