首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在预提交钩子中停止git提交并退出

在预提交钩子中停止git提交并退出
EN

Stack Overflow用户
提问于 2015-06-03 01:45:22
回答 1查看 4.1K关注 0票数 5

我试着阻止git提交继续使用预提交钩子。在阅读手册时,当您返回除0以外的退出代码时,它应该停止。我正在测试csscomb命令是否返回错误,以及它是否会中断循环和退出,但是git提交仍然继续通过git commit (-a)输入消息。

我从https://github.com/filtercake/git-pre-commit-csscomb中分叉并修改了下面的脚本

代码语言:javascript
复制
#!/bin/bash

# pre-commit hook to comb staged .sass and .scss files
# save as .git/hooks/pre-commit
# make executable: chmod +x .git/hooks/pre-commit

# sources:

# http://www.hagenburger.net/BLOG/Using-Git-Commit-Hooks-to-Autocompile-Sass-to-CSS.html
# http://stackoverflow.com/questions/8470755/git-pre-commit-hook-add-file-into-index/8471009#8471009
# http://stackoverflow.com/questions/592620/how-to-check-if-a-program-exists-from-a-bash-script/677212#677212
# https://gist.github.com/openam/8406343

# check if sass/scss files are staged for commit

# diff-lines from http://stackoverflow.com/a/12179492/3019532
# takes the line
function diff-lines() {
    local path=
    local line=
    while read; do
        esc=$'\033'
        if [[ $REPLY =~ ---\ (a/)?.* ]]; then
            continue
        elif [[ $REPLY =~ \+\+\+\ (b/)?([^[:blank:]$esc]+).* ]]; then
            path=${BASH_REMATCH[2]}
        elif [[ $REPLY =~ @@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@.* ]]; then
            line=${BASH_REMATCH[2]}
        elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then
            echo "Line $line:$REPLY"
            if [[ ${BASH_REMATCH[2]} != - ]]; then
                ((line++))
            fi
        fi
    done
}

if ! git diff --quiet --cached -- **/*.{sass,scss}; then

            echo ""
            echo "--> you checked in sass/scss files. lets comb them..."
            echo ""

            # check if csscomb is installed

            if hash csscomb 2>/dev/null; then

                echo -e "\033[1;32m--> found csscomb\033[0m"

                # TODO: check for csscomb update once a week

                # check if configfile exists

                if [ ! -f ./.csscomb.json ]; then
                    echo "--> no config file, using defaults"
                else
                    echo -e "\033[1;32m--> found .csscomb.json\033[0m"
                fi

                echo ""

                # Necessary check for initial commit
                against="4b825dc642cb6eb9a060e54bf8d69288fbee4904"
                git rev-parse --verify HEAD >/dev/null 2>&1 && against="HEAD"
                EXITCODE=0

                # (A)dded (C)opied or (M)odified
                # encapsulate the loop in {} http://stackoverflow.com/a/13665483/3019532
                git diff-index --cached --full-index --diff-filter=ACM $against | \
                {
                    while read -r line; do
                      FILE_PATH="$(echo ${line} |cut -d' ' -f6-)"
                      EXTENSION="${FILE_PATH##*.}"
                      # EXTENSION=${EXTENSION,,} # Convert to lowercase
                      REGEX=""

                      # Select discouraged words based on extension

                      if [ "${EXTENSION}" = "sass" ] || [ "${EXTENSION}" = "scss" ]; then
                        echo "--> staged sass/scss file: " $FILE_PATH
                        echo "--> combing..."
                        if csscomb $FILE_PATH; then
                            echo "--> adding combed file"
                            git add $FILE_PATH
                            echo "--> done"
                        else
                            echo "Check your CSS file for combing errors or alternatively add '-n' to your git commit to bypass this hook"
                            break
                            exit 1 # Should stop the git commit from continuing
                        fi
                      fi
                    done
                }
            else
                echo -e "\033[0;31m--> Oh noes, CSS Comb is not installed. Do:"
                echo "--> npm install csscomb -g"
                echo -e "\033[0m"
                echo "--> (you need to change and stage a sass/scss file again to see it work on the next commit...)"
                echo ""
            fi
fi

# Necessary check for initial commit
against="4b825dc642cb6eb9a060e54bf8d69288fbee4904"
git rev-parse --verify HEAD >/dev/null 2>&1 && against="HEAD"
EXITCODE=0

exit 0
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-03 02:17:59

代码语言:javascript
复制
            git diff-index --cached --full-index --diff-filter=ACM $against | \
            {
                while read -r line; do

这是你的麻烦。多命令管道阶段在子subshell中运行,该循环的出口退出其子subshell。Subshell也有自己的环境,因此您也不能从它们传递变量设置。

代码语言:javascript
复制
while read -r; do
        if ! good $REPLY; then exit 1; fi
done <<EOD
$(git diff-index --cached --full-index --diff-filter=ACM $against)
EOD
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30609480

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档