有没有办法检查一个git标签是否与相应提交的内容匹配? [英] Is there a way to check that a git tag matches the content of the corresponding commit?

查看:153
本文介绍了有没有办法检查一个git标签是否与相应提交的内容匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我工作的公司中,一些项目有一个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆