简体   繁体   中英

Git pre-commit bash script on Windows

I've created a simple pre-commit script for 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

The check if [ -n "grep -E ':\\s*DbMigration\\s' $FILE" ] fails miserably in the sense that it generates false positives.

Versions involved are:

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)

What gives?

Update

Some examples:

 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

The test

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

doesn't run the command, it tests if the string inside "" is not empty. And it is not empty so the test always succeed!

To run the command and test its output use backticks instead of double quotes:

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

or use $() :

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

You have to start a subshell to execute the command.

To test for an empty string, you have to do it like this:

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

This yields correct with all the given test cases you provided.

The bash script that seems to fit the bill turned out to be this one:

#!/bin/sh

RED='\033[0;31m'
NC='\033[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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM