首页 > 解决方案 > 如何访问和比较在 git pre receive 钩子中更改了哪个文件

问题描述

我是 git hooks 的新手,现在我有一个简单的请求,需要我检查项目中的配置文件。

例如,我有一个 spring-boot 配置文件:application.yml,它的内容是:

spring:
  profiles:
    active: prod

masterandrelease分支中,我需要确保文件是

spring:
  profiles:
    active: prod

dev分支中,我需要它是:

spring:
  profiles:
    active: dev

现在我需要一个预接收挂钩来检查是否application.yml已修改。如果更改了,我需要检查正确的分支是否对应正确的文件内容。否则,推送行为将被拒绝。

我正在使用 GitLab,我知道将文件放在哪里。但我不知道如何编写脚本,或者我的请求是否可以使用预接收脚本来满足。我花了一整天的时间阅读 git doc,但我得到的帮助很少。如果有人有解决方案或任何文档参考将不胜感激。

标签: gitgithooks

解决方案


经过一天的搜索,我找到了我想要的答案。
由于我是 git hook 新手,这是我第一次使用它。我想我需要更多地了解 git
非常感谢您的建议 @torek

#!/bin/bash

oldrev=$1
newrev=$2
refname=$3
z40=0000000000000000000000000000000000000000

echo 'start git pre receive checking...............'
while read oldrev newrev refname; do
    # Get a list of all objects in the new revision
    objects=`git ls-tree --full-name -r ${newrev}`
    echo "in loop"
    # Get the file names, without directory, of the files that have been modified
    # between the new revision and the old revision
    
    if [ "$oldrev" = $z40 ] ; then
                # handle the case when new branch was create
        oldrev="4b825dc642cb6eb9a060e54bf8d69288fbee4904"
    fi

    if [ "$newrev" = $z40 ]; then
                # handle the case when branch was deleted
        newrev="4b825dc642cb6eb9a060e54bf8d69288fbee4904"
    fi
        # get file name
    objects=`git ls-tree --full-name -r ${newrev}`
    
    git diff --name-only $oldrev $newrev | while read file; do
        
                # grep file name, find the file that I need
        object=`echo -e "${objects}" | egrep "(\s)${file}\$" | egrep 'application.properties$' | awk '{ print $3 }'`
        # If it's not present, then continue to the the next itteration
        if [ -z ${object} ]; 
        then 
            echo "not application.properties : ${file}"
            continue; 
        fi
                # get the file that I want
        echo "get change file: ${file}"
        echo "get remote refname: ${refname}"
                # check the remote banch
        if test -z "$(  echo $refname | egrep 'release$'  )"; then
                echo "ref不是release."
                                # checkout the file content
                if test -z "$( git show $newrev:$file | egrep 'dev' )"; then
                        echo "properties file didn't have dev, please check it"
                        exit 1
                else
                        echo "properties file got dev, yes! "
                        exit 0
                fi

        else
                echo "remote ref is release."
                if test -z "$( git show $newrev:$file | egrep 'prod' )"; then
                        echo "properties has no prod,please check"
                        exit 1
                else
                        echo "properties got prod, yes"
                        exit 0
                fi

        fi
        echo "out put changed config file"
        #  git show $newrev:$file
    done
done

推荐阅读