Search code examples
regexgithookcommit

Regex for git commit-msg hook


I am trying to achieve following structure for git commit msg:

X=Uppercase character
Y=Number 0-9
category=fix, chore, doc, etc...

XXXXY-YYY [category] XXXXX*

this is my commit-msg file

MSG_FILE=$1
FILE_CONTENT="$(cat $MSG_FILE)"
# Initialize constants here
export REGEX="\D\D\D\D\d-\d\d\d \[(fix|poc|chore|feat|refactor|style|test)\] .*"
export ERROR_MSG="Commit message format must match regex \"${REGEX}\""
if [[ $FILE_CONTENT =~ $REGEX ]]; then
 echo "Nice commit!"
else
  echo "Bad commit \"$FILE_CONTENT\", check format."
 echo $ERROR_MSG
 exit 1
fi
exit 0

But all I get is:

    $ git commit -m "PBCL2-666 [fix] whatever"
Bad commit "PBCL2-666 [fix] whatever", check format.
Commit message format must match regex "\D\D\D\D\d-\d\d\d \[(fix|poc|chore|feat|refactor|style|test)\] .*"

Any ideas?


Solution

  • You are using the regex in Bash and thus using the POSIX ERE regex engine.

    POSIX ERE does not recognize the \D construct matching any non-digit char. Use [0-9] to match a digit (or [[:digit:]]) and [^0-9] (or [^[:digit:]]) to match a non-digit.

    However, you need [[:upper:]] to match any uppercase letter.

    FILE_CONTENT="PBCL2-666 [fix] whatever"
    # ....
    ERROR_MSG="Commit message format must match regex \"${REGEX}\""
    REGEX="^[[:upper:]]{4}[0-9]-[0-9]{3} \[(fix|poc|chore|feat|refactor|style|test)] .*"
    if [[ $FILE_CONTENT =~ $REGEX ]]; then
     echo "Nice commit!"
    else
      echo "Bad commit \"$FILE_CONTENT\", check format."
     echo $ERROR_MSG
     exit 1
    fi
    

    See the online Bash demo.

    Note I added ^ at the start to make sure matching starts from the beginning of string only.