user2356180 user2356180 - 1 year ago 108
Bash Question

Shell/Git Script: Pattern matching for the current commit message

I'm trying to do a hook for a message that you're about to commit on git. What I usually do when about to commit is [SOME_DESCRIPTION] Refs #[0-9]+

I've never done shell scripting before but I'm fairly adept at programming in general. I'm trying to write a script in commit-msg that will validate if the current that you're trying to save has the pattern "*Refs #[0-9]+". But I have no shell syntax experience and not too much linux.

  • I think $1 is to get the current commit message, but I'm probably wrong.

  • And my way of checking for the pattern is probably way wrong

if [[ $requireTicketRef == *Refs \#[0-9]+ ]]
echo "Contains ticket reference"
exit 0
echo "Need to add ticket reference"
exit 1

Answer Source

Assuming you're right about $1 being the commit message, your code is close, but the patterns that bash uses with == in [[...]] are not regular expressions. They are instead the same sort of wildcards used to expand filenames, usually called "globs", which don't normally have the ability to quantify specific matches (like "1 or more digits").

(They also have to be a single word, so you need another backslash in front of the space between Refs and the #. And you actually don't need one in front of the # when it's not the first thing in a word.)

You have a couple options to fix this. The simplest is probably to use actual regular expressions, which you can do inside [[...]] by just using =~ instead of ==:

if [[ ! $requireTicketRef =~ Refs\ #[0-9]+ ]]; then 
  echo >&2 "Need to add ticket reference."
  exit 1

The other option would be to turn on the extglob ("extended glob") option, which borrows some syntax from the Korn shell to bring regex-like capabilities (negation, alternation, quantification) to glob patterns.

shopt -s extglob
if [[ ! $requireTicketRef == *Refs\ #+([0-9])* ]]; then 
  echo >&2 "Need to add ticket reference."
  exit 1