有没有办法检查一个git标签是否与相应提交的内容匹配? [英] Is there a way to check that a git tag matches the content of the corresponding commit?
问题描述
在我工作的公司中,一些项目有一个 project.info
文件,其中包含程序/库/当前版本。
实际上,当有人想要标记一个版本时,他必须首先确保 project.info
文件(它是版本化的)并且包含与他将要创建的标签的名称相同的版本。没有必要说这是容易出错的。
我们为git开发了一个客户端 - 服务器工作流程(所有提交到同一个中央存储库),所以我想知道:是有一种方法(或许是一个钩子)来让这个中央仓库拒绝 project.info
不匹配的标签吗?
我该如何开始?
非常感谢。
这是我最后的 更新
钩子脚本:
#!/ bin / sh
#
#一个阻止未注释标签进入的示例钩子脚本。
#由带有参数的git receive-pack调用:refname sha1-old sha1-new
#
#要启用此钩子,请将此文件重命名为update。
#
#配置
#------
#hooks.allowunannotated
#此布尔值设置是否允许unannotated标签进入
#存储库。默认情况下他们不会。
#hooks.allowdeletetag
#此布尔值设置是否允许在
#存储库中删除标签。默认情况下他们不会。
#hooks.allowmodifytag
#这个布尔值设置标签是否可以在创建后修改。默认
#不会。
#hooks.allowdeletebranch
#此布尔值设置是否允许在
#存储库中删除分支。默认情况下他们不会。
#hooks.denycreatebranch
#这个布尔值设置远程创建分支是否会被拒绝存储库中的
#。默认情况下这是允许的。
#
#---命令行
refname =$ 1
oldrev =$ 2
newrev =$ 3
#---安全检查
如果[-z$ GIT_DIR];那么
回显不要从命令行运行此脚本。 >& 2
echo(如果你愿意,你可以提供GIT_DIR然后运行>& 2
echo$ 0< ref>< oldrev>< newrev>)> ;& 2
exit 1
fi
if [-z$ refname-o -z$ oldrev-o -z$ newrev];那么
回声用法:$ 0< ref>< oldrev>< newrev> >& 2
exit 1
fi
#---配置
allowunannotated = $(git config --bool hooks.allowunannotated)
allowdeletebranch = $(git config --bool hooks.allowdeletebranch)
denycreatebranch = $(git config --bool hooks.denycreatebranch)
allowdeletetag = $(git config --bool hooks.allowdeletetag)
allowmodifytag = $(git config --bool hooks.allowmodifytag)
allowwildtag = $(git config --bool hooks.allowwildtag)
allowunmatchedtag = $(git config --bool hooks.allowunmatchedtag)
#查询没有说明
projectdesc = $(sed -e'1q'$ GIT_DIR / description)
案例
中的$ projectdesc未命名的存储库 * | )
echo***项目描述文件尚未设置>& 2
exit 1
;;
esac
#---检查类型
#if $ newrev是0000 ... 0000,这是一个提交删除一个ref。
zero =0000000000000000000000000000000000000000
if [$ newrev=$ zero];然后
newrev_type =删除
else
newrev_type = $(git cat-file -t $ newrev)
fi
case$ refname,
refs / tags /}
$ !=true];那么
echo***未注释的标签$ short_refname在这个存储库中是不允许的>& 2
echo***使用'git tag [-a | -s ]'为你想要传播的标签。 >& 2
exit 1
fi
;;
refs / tags / *,delete)
#删除标记
if [$ allowdeletetag!=true];那么
回声***删除标签不被允许在这个仓库中>& 2
exit 1
fi
;;
refs / tags / *,tag)
#带注释的标签
if [$ allowwildtag!=true]&& ./hooks/check_tag -r $ refname> / dev / null 2>& 1
then
echo*** Tag'$ refname'与命名约束不匹配。 >& 2
echo***标签必须遵循'x.y-z'模式,其中x,y和z是数字字符。 >& 2
exit 1
fi
if [$ allowmodifytag!=true]&& git rev-parse $ refname> / dev / null 2>& 1
然后
echo*** Tag'$ refname'already exists。 >& 2
echo***此储存库不允许修改标记。 >& 2
exit 1
fi
if [$ allowunmatchedtag!=true]
then
project_version =`。/ hooks / extract_project_version $ newrev 2> / dev / null`
if [$ project_version==]
然后
#我们在成功的情况下不输出任何东西
#回声***项目不包含project.info文件,没有标签匹配执行。
:
elif [$ project_version==error]
然后
#该项目包含一个无效的project.info:我们接受标签,但警告它。
echo*** Project包含一个无效的project.info文件,没有执行标签匹配。
else
tag_version = $ {refname ## refs / tags /}
if [$ project_version!=$ tag_version]
then
回声***标签和项目版本不匹配:$ tag_version!= $ project_version
回声***请检查您的project.info文件。
出口1
fi
fi
fi
;;
refs / heads / *,commit)
#branch
if [$ oldrev=$ zero-a$ denycreatebranch=true];那么
回显***在这个仓库中不允许创建一个分支>& 2
exit 1
fi
;;
refs / heads / *,delete)
#删除分支
if [$ allowdeletebranch!=true];那么
回显***删除一个分支在这个仓库中是不允许的>& 2
exit 1
fi
;;
refs / remotes / *,commit)
#tracking branch
;;
refs / remotes / *,delete)
#删除跟踪分支
if [$ allowdeletebranch!=true];然后
回显***删除跟踪分支不允许在这个仓库中>& 2
exit 1
fi
;;
*)
#还有其他什么东西(还有什么?)
回声***更新挂钩:未知类型的更新ref $ $ refname的类型$ newrev_type>& 2
出口1
;;
esac
#---完成
出口0
以下是我的 extract_project_version
脚本:
#!/ bin / bash
rev = $ 1
if [$ rev==]
然后
echo缺少修订参数。 >& 2
exit 1
fi
tmpdir = / tmp / $$。extract_project_version
mkdir -p $ tmpdir
git archive $ rev | tar -x -C $ tmpdir
if [-e$ tmpdir / project.info]
然后
echo $ tmpdir / project.info
fi
rm -rf $ tmpdir
现在它可以很好地工作: p>
In the company I work for, some projects have an project.info
file which contains the current version of the program/library/whatever.
Actually, when someone wants to tag a version, he must first ensure that the project.info
file (which is versionned) is up-to-date and contains the same version than the name of the tag he is about to create. No need to say that this is error prone.
We work on a clients-server workflow for git (all commits go to the same central repository) so I wonder: is there a way (a hook perhaps ?) to make this central repository refuse tags for which the project.info
does not match ?
What should I look for to get started ?
Thank you very much.
Thanks to all the advices here, I succeeded.
Here is my final update
hook script:
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
# This boolean sets whether unannotated tags will be allowed into the
# repository. By default they won't be.
# hooks.allowdeletetag
# This boolean sets whether deleting tags will be allowed in the
# repository. By default they won't be.
# hooks.allowmodifytag
# This boolean sets whether a tag may be modified after creation. By default
# it won't be.
# hooks.allowdeletebranch
# This boolean sets whether deleting branches will be allowed in the
# repository. By default they won't be.
# hooks.denycreatebranch
# This boolean sets whether remotely creating branches will be denied
# in the repository. By default this is allowed.
#
# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"
# --- Safety check
if [ -z "$GIT_DIR" ]; then
echo "Don't run this script from the command line." >&2
echo " (if you want, you could supply GIT_DIR then run" >&2
echo " $0 <ref> <oldrev> <newrev>)" >&2
exit 1
fi
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
exit 1
fi
# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)
allowwildtag=$(git config --bool hooks.allowwildtag)
allowunmatchedtag=$(git config --bool hooks.allowunmatchedtag)
# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
echo "*** Project description file hasn't been set" >&2
exit 1
;;
esac
# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"
if [ "$newrev" = "$zero" ]; then
newrev_type=delete
else
newrev_type=$(git cat-file -t $newrev)
fi
case "$refname","$newrev_type" in
refs/tags/*,commit)
# un-annotated tag
short_refname=${refname##refs/tags/}
if [ "$allowunannotated" != "true" ]; then
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
exit 1
fi
;;
refs/tags/*,delete)
# delete tag
if [ "$allowdeletetag" != "true" ]; then
echo "*** Deleting a tag is not allowed in this repository" >&2
exit 1
fi
;;
refs/tags/*,tag)
# annotated tag
if [ "$allowwildtag" != "true" ] && ./hooks/check_tag -r $refname > /dev/null 2>&1
then
echo "*** Tag '$refname' does not match the naming constraints." >&2
echo "*** Tags must follow the 'x.y-z' pattern, where x, y, and z are numeric characters." >&2
exit 1
fi
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
then
echo "*** Tag '$refname' already exists." >&2
echo "*** Modifying a tag is not allowed in this repository." >&2
exit 1
fi
if [ "$allowunmatchedtag" != "true" ]
then
project_version=`./hooks/extract_project_version $newrev 2>/dev/null`
if [ "$project_version" == "" ]
then
# We dont output anything in case of success
#echo "*** Project does not contain a project.info file. No tag match performed."
:
elif [ "$project_version" == "error" ]
then
# The project contains an invalid project.info: we accept the tag but warn about it.
echo "*** Project contains an invalid project.info file. No tag match performed."
else
tag_version=${refname##refs/tags/}
if [ "$project_version" != "$tag_version" ]
then
echo "*** Tag and project version do not match: $tag_version != $project_version"
echo "*** Please check your project.info file."
exit 1
fi
fi
fi
;;
refs/heads/*,commit)
# branch
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
echo "*** Creating a branch is not allowed in this repository" >&2
exit 1
fi
;;
refs/heads/*,delete)
# delete branch
if [ "$allowdeletebranch" != "true" ]; then
echo "*** Deleting a branch is not allowed in this repository" >&2
exit 1
fi
;;
refs/remotes/*,commit)
# tracking branch
;;
refs/remotes/*,delete)
# delete tracking branch
if [ "$allowdeletebranch" != "true" ]; then
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
exit 1
fi
;;
*)
# Anything else (is there anything else?)
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
exit 1
;;
esac
# --- Finished
exit 0
And here is my extract_project_version
script:
#!/bin/bash
rev=$1
if [ "$rev" == "" ]
then
echo "Missing revision parameter." >&2
exit 1
fi
tmpdir=/tmp/$$.extract_project_version
mkdir -p $tmpdir
git archive $rev | tar -x -C $tmpdir
if [ -e "$tmpdir/project.info" ]
then
echo $tmpdir/project.info
fi
rm -rf $tmpdir
And now it works perfectly :)
这篇关于有没有办法检查一个git标签是否与相应提交的内容匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!