如何区分git分支名称和提交哈希?

如何区分git分支名称和提交哈希?,git,bash,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

我有一个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
#/bin/bash
提交或分支=“$1”
cd/path/to/my_repo
git获取
如果
然后
回声“这是一个分支”
其他的
回应“这是一个承诺”
fi
您可以使用:

如果它是空的,则它是一个SHA1(或无效对象,这不好)。
如果不是,则为分支名称


更好的技术来自“”,使用:

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

SHA1将产生相同的结果(或至少):

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

在我看来,您无法可靠地检查这一点,因为哈希也是有效的分支名称。尝试:

git checkout -b 0c8158f47d7dda89226d4e816fee1fb9ac6c1204
这意味着可能存在这样一种情况,即具有该名称的分支存在,但也存在提交


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

正如@VonC和@hek2mgl所提到的,这可能不是一个或另一个测试。您可以将脚本稍微修改为以下内容(借用自:


请注意,这只测试本地分支。请查看您是否对远程分支感兴趣。

如果您想要一个可靠的机制来告诉相对名称(例如,您可能在命名分支后面有一个或多个提交),您可以使用
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
参考:

更新:正如@kporter所提到的,还有
--仅名称
标志(自2020年4月21日起新提交):


命令行参考:

@hek2mgl True,我已经相应地更新了过滤器。当我这样做时会发生什么:
git checkout-b$(git rev parse HEAD)
?upvote仍然是你的,但是嘿!:d他们都使用HEAD,而不是sha。为什么在确定参数是否为提交哈希时,
git show ref--HEAD--sha | grep-q^参数
比git merge base更差?在哪些情况下?@Rihad任何脚本都不应该尝试grep命令输出,但应该能够比较它们记录的r结果,就像在git merge base中一样。就脚本而言,这更健壮。尽管如此,两者都应该工作。还值得注意的是,一些命令(例如,
git rev parse
)会将其视为原始SHA-1,而其他命令(例如,
git checkout
)会将其视为原始SHA-1将其视为分支名称。若要强制将其视为分支名称,请在前面添加
refs/heads/
git checkout
无法强制将其视为SHA-1,但它不是必需的,因为
git checkout--detach
将从分支中分离,这是您希望
git checkout
进行处理的唯一情况不管怎么说,我的名字不是生硬的SHA-1。@torek我远不是git大师,只是熟悉每天的事情,还有一点。愚蠢的问题,你的评论是支持我的答案还是反对我的答案?不是反对,只是扩展一下而已-名字确实可能是模棱两可的,git在消除歧义方面并不总是有多大帮助,但你是对的大多数情况下,这都无关紧要。在这种情况下,你必须有点特别,因此才会有评论。就这个问题而言,这真的很重要吗?我想为一个分支和一个提交做不同的事情。比如,如果它是一个分支,我可能想记录当前头的实际提交哈希。如果它是一个分支,我会记录ht需要
git pull
,而提交则不需要。如果是提交,我可能想检查它是哪个分支的一部分。以及其他任何东西。谢谢!这非常有效
git name rev$commit|u HASH | awk'{print$2}“
@barakbd您可以删除awk:
git name rev--name only$COMMIT_HASH
如何执行相同操作,但当且仅当引用位于命名对象的顶部时?因此,在上述示例中
79e10e8
HEAD~20
应返回“未定义”或失败。@0andriy看起来像
git
将只找到最近的命名对象对象,并使用它?这是新克隆的输出(但请从上面查看
7530a95
):
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
git checkout -b 0c8158f47d7dda89226d4e816fee1fb9ac6c1204
#!/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
$ 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 name-rev HEAD
HEAD tags/last_sha_with_original_matlab~313
$ git name-rev --name-only HEAD~20
tags/last_sha_with_original_matlab~333