Git 在 Windows 上预提交 bash 脚本

Git pre-commit bash script on Windows

我已经为 git 创建了一个简单的预提交脚本:

#!/bin/sh

if git rev-parse —verify HEAD >/dev/null 2>&1; then
    against=HEAD
else
    against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

for FILE in `git diff --cached --name-only` ; do
    # Check if the file contains 'DbMigration'
    echo $FILE $against
    if [ -n "grep -E ':\s*DbMigration\s' $FILE" ];
    then
        echo ''
        echo ''
        echo '[**CODEPOLICE**]'
        echo '[**CODEPOLICE**]' $FILE
        echo '[**CODEPOLICE**]'
        echo '[**CODEPOLICE**] This file contains a direct subclass of DbContext! Refactor your migrations to use <...> instead!'
        echo '[**CODEPOLICE**]'
        echo ''
        echo ''
        exit 1
    fi
done

exit

检查 if [ -n "grep -E ':\s*DbMigration\s' $FILE" ] 悲惨地失败了,因为它产生了误报。

涉及的版本有:

Windows 10 Enterprise

$ git --version
git version 2.15.1.windows.2

$ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-msys)

什么给了?

更新

一些示例:

 public partial class Initial : DbMigration --> we want positive & we get positive --> ok

 public partial class Initial : FoobarDbMigration --> we want negative & we get positive --> not ok

 public partial class Initial : Foobar --> we want negative & we get positive --> not ok

 public partial class Initial : DbMigrationFoobar --> we want negative & we get positive --> also not ok

测试

[ -n "grep -E ':\s*DbMigration\s' $FILE" ]

不是 运行 命令,它测试 "" 中的字符串是否不为空。而且它不是空的,所以测试总是成功的!

到 运行 命令并测试其输出使用反引号而不是双引号:

[ -n "`grep -E ':\s*DbMigration\s' $FILE`" ]

或使用$():

[ -n "$(grep -E ':\s*DbMigration\s' $FILE)" ]

您必须启动子 shell 才能执行命令。

要测试空字符串,您必须这样做:

[ -n "$(grep -E ':\s*DbMigration\s' $FILE)" ]

这对您提供的所有给定测试用例都是正确的。

似乎符合要求的 bash 脚本竟然是这个:

#!/bin/sh

RED='3[0;31m'
NC='3[0m' # No Color

echo ""
echo -n "[**CODEPOLICE**] Checking for usages of 'DbMigration' over 'VNextDbMigration' ... "

stagedFiles=`git diff --cached --name-only`
while read -r FILE ; do
    # Check if the file contains ': DbMigration'

    if [ -f "$FILE" ];
    then
        matchingLines=$( grep -P ":(\s|\r|\n)*DbMigration(\s|$)" "$FILE" )
        if [ "$matchingLines" != "" ];
        then
            echo -e ""
            echo -e "${RED}[**CODEPOLICE**]${NC}"
            echo -e "${RED}[**CODEPOLICE**]${NC}" $FILE
            echo -e "${RED}[**CODEPOLICE**]${NC}"
            echo -e "${RED}[**CODEPOLICE**]${NC} ^- This file contains a direct subclass of 'DbContext'! Refactor your migration to have it inherit from 'VNextDbMigration' instead!"
            echo -e "${RED}[**CODEPOLICE**]${NC}"
            echo -e ""
            echo -e ""
            exit 1
        fi
    fi
done <<< $stagedFiles

echo "ALL OK"
echo ""

exit