如何从带注释的标签中获取附加提交的哈希值
How to get the hash of the attached commit from an annotated tag
我想做的是创建一个预推送挂钩,它需要一个标记指向与当前 HEAD 相同的提交。我们以一种稍微不寻常的方式使用 git,并且在任何情况下最新的提交都不应该有标签。我有一个有效的实现,但发现它只适用于轻量级标签。
head=$(git rev-parse HEAD)
last_tag=$(git rev-parse $(git describe --tags))
if [ "$head" != "$last_tag" ]
then
echo >&2 'Aborting push - there is no tag on the latest commit.'
exit 1
fi
我发现的问题是,即使在设置 push.followTags
之后,轻量级标签也会被忽略。无需额外步骤即可推送和拉取标签对我来说很重要,因为我们会大量使用它们。
要解决此问题,我们可以使用带注释的标签。问题是带注释的标签有它自己的散列,由 git rev-parse
返回。我无法找到一种方法来获取标签链接到的提交的哈希值。我都试过了
git rev-parse tagname^
git rev-parse $(git rev-parse tagname)^
知道如何做到这一点,或者是否有其他更好的选择?
我打算将其作为副本关闭,但 在 副本中接受的答案不一定是最好的方法。
最好的方法是使用git rev-parse tagname^{}
或git rev-parse tagname^{commit}
。
它们之间的主要区别在于前者跟随标签到某个非标签对象——可能是提交,但也可能是树或 blob——而后者跟随标签到提交。如果标记不指向提交(直接或间接),则第二种形式会产生一条错误消息(到 stderr)和一个非零状态:
hash=$(git rev-parse ${tag}^{commit}) || exit
或者,如果您不介意 $tag
命名树或 blob 对象:
hash=$(git rev-parse ${tag}^{}) || exit
当给定一个指向树或 blob 的标签时,git log
方法将不会产生任何输出(并成功退出):
$ git tag -a foo -m test HEAD^{tree}
$ git log foo
$ git rev-parse foo
98769d20d108a98555aafab76b0e3b84a3719779
$ git rev-parse foo^{}
f7a4925fb621cdef69d7dec49159c13cfc6aa789
$ git rev-parse foo^{commit}
error: foo^{commit}: expected commit type, but the object dereferences to tree type
foo^{commit}
error: foo^{commit}: expected commit type, but the object dereferences to tree type
fatal: ambiguous argument 'foo^{commit}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
$ $ git tag -d foo
Deleted tag 'foo' (was 98769d20d1)
通过使用 ^{}
或 ^{commit}
符号,您可以选择您想要的行为。
我想做的是创建一个预推送挂钩,它需要一个标记指向与当前 HEAD 相同的提交。我们以一种稍微不寻常的方式使用 git,并且在任何情况下最新的提交都不应该有标签。我有一个有效的实现,但发现它只适用于轻量级标签。
head=$(git rev-parse HEAD)
last_tag=$(git rev-parse $(git describe --tags))
if [ "$head" != "$last_tag" ]
then
echo >&2 'Aborting push - there is no tag on the latest commit.'
exit 1
fi
我发现的问题是,即使在设置 push.followTags
之后,轻量级标签也会被忽略。无需额外步骤即可推送和拉取标签对我来说很重要,因为我们会大量使用它们。
要解决此问题,我们可以使用带注释的标签。问题是带注释的标签有它自己的散列,由 git rev-parse
返回。我无法找到一种方法来获取标签链接到的提交的哈希值。我都试过了
git rev-parse tagname^
git rev-parse $(git rev-parse tagname)^
知道如何做到这一点,或者是否有其他更好的选择?
我打算将其作为副本关闭,但 在 副本中接受的答案不一定是最好的方法。
最好的方法是使用git rev-parse tagname^{}
或git rev-parse tagname^{commit}
。
它们之间的主要区别在于前者跟随标签到某个非标签对象——可能是提交,但也可能是树或 blob——而后者跟随标签到提交。如果标记不指向提交(直接或间接),则第二种形式会产生一条错误消息(到 stderr)和一个非零状态:
hash=$(git rev-parse ${tag}^{commit}) || exit
或者,如果您不介意 $tag
命名树或 blob 对象:
hash=$(git rev-parse ${tag}^{}) || exit
当给定一个指向树或 blob 的标签时,git log
方法将不会产生任何输出(并成功退出):
$ git tag -a foo -m test HEAD^{tree}
$ git log foo
$ git rev-parse foo
98769d20d108a98555aafab76b0e3b84a3719779
$ git rev-parse foo^{}
f7a4925fb621cdef69d7dec49159c13cfc6aa789
$ git rev-parse foo^{commit}
error: foo^{commit}: expected commit type, but the object dereferences to tree type
foo^{commit}
error: foo^{commit}: expected commit type, but the object dereferences to tree type
fatal: ambiguous argument 'foo^{commit}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
$ $ git tag -d foo
Deleted tag 'foo' (was 98769d20d1)
通过使用 ^{}
或 ^{commit}
符号,您可以选择您想要的行为。