如何从提交哈希中告诉git branch name?

时间:2015-04-17 18:53:43

标签: git bash

我有一个bash脚本,它接受一个分支名称(例如“master”或“feature / foo”)或提交哈希(例如“1234abcd”)的字符串。

我已经检出了存储库,所以我可以调用git。

确定字符串是分支名称还是提交哈希值的最佳方法是什么?

#!/bin/bash
commit_or_branch="$1"
cd /path/to/my_repo
git fetch
if <is_branch $commit_or_branch>
then
    echo "it's a branch"
else
    echo "it's a commit"
fi

4 个答案:

答案 0 :(得分:6)

如果您想要一个强大的机制来告诉相对名称(例如,SHA1可能是一个左右提交命名分支),您可以使用git name-rev来解决它。

示例:

$ git config remote.upstream.url
https://github.com/RobotLocomotion/drake.git

$ git log --oneline -n 5
7530a95 Merge pull request #5743 from soonho-tri/pr-reformat-mathematical_program
ebc8f25 Suppresses console output of speed_bump.obj genrule. (#5726)
d8b9a0b Merge pull request #5735 from david-german-tri/namespaces
79e10e8 Remove redundant 'symbolic::' prefix from mathematical_program code
b68b590 Clean up mathematical_program code by adding using std::*

$ git name-rev HEAD
HEAD master
$ git name-rev 79e10e8
79e10e8 master^2
$ git name-rev HEAD~20
HEAD~20 remotes/origin/issue/5646_return_binding~3

```

参考:Git Tips

答案 1 :(得分:2)

您可以使用git show-ref

git show-ref --head | grep refs

如果它为空,则为SHA1(或无效对象,不好)。
如果没有,则为分支名称。


更好的技术来自&#34; Validate if commit exists&#34;,使用git merge-base

分支名称将产生不同的字符串(SHA1)

C:\Users\vonc\prog\b2d>git merge-base master master
de4accfd28c5f25fcc057d56996b83450be5dc60

SHA1将产生相同的结果(或至少starts with the same result):

C:\Users\vonc\prog\b2d>git merge-base 03949c3d3f88a378c6a08e57daa97059b52813f1 03949c3d3f88a378c6a08e57daa97059b52813f1
03949c3d3f88a378c6a08e57daa97059b52813f1

foobar将失败:

C:\Users\vonc\prog\b2d>git merge-base xxx xxx
fatal: Not a valid object name xxx

这意味着:

if [[ git merge-base $string $string ]]; then
  if [[ $(git merge-base $string $string) == $string* ]]; then
    echo "SHA1"
  else
    echo "branch"
  fi
else
  echo "Not a valid object name '$string'"
fi

答案 2 :(得分:1)

Imo你无法可靠地检查这个,因为哈希也是一个有效的分支名称。尝试:

git checkout -b 0c8158f47d7dda89226d4e816fee1fb9ac6c1204

这意味着可能存在具有该名称的分支存在但也存在提交的情况。

由于您可以将分支名称或提交传递给大多数git命令,因此您无需区分它们。

答案 3 :(得分:-1)

正如@VonC和@ hek2mgl所提到的,这可能不是一个或另一个测试。您可以稍微修改一下这样的脚本(借鉴this SO answer

#!/bin/bash
commit_or_branch="$1"
cd /path/to/my_repo
git fetch
if git branch | grep $commit_or_branch 2> /dev/null
then
    echo "it's a branch"
fi

if git cat-file -e $commit_or_branch 2> /dev/null
then
  echo "it's a commit"
fi

请注意,这仅测试本地分支..如果您对远程分支感兴趣,请参阅this post