2

I am trying to set up a python pre-commit hook that enforces referencing a JIRA id in the commit message. If this JIRA id is not present the commit is rejected/the hook fails. I have a .pre-commit-config.yaml set up and a dedicted commit-msg.py that returns the non-zero exit code if the commit message does not contain the reference. A commit message without this reference is correctly rejected but when I add the reference and commit again this commit also fails.

I open the file COMMIT_EDITMSG, read the lines and use the python module re to compare the start of the commit message with a regex. The script looks like

msg_temp_file = './.git/COMMIT_EDITMSG'

with open(msg_temp_file, "r", encoding="utf-8") as f_msg:
    lines = f_msg.readlines()

# Remove the comment lines in the commit message.
commit_message = [line for line in lines if not line.strip().startswith("#")][0]
print(commit_message)
if not re.match("\[PRO\-[0-9]+\]", commit_message):
    print('-------------------------------------------------------')
    print('Commit message does not reference a JIRA id!')
    print('-------------------------------------------------------')
    sys.exit(1)

And my config.yaml:

repos:
- repo: local
  hooks:
  - id: commit-msg
    name: Enforce commit strategy
    description: make sure an epic id is correctly mentioned in the commit message
    entry: python ./commit-msg.py
    language: system
    pass_filenames: false
    always_run: true
    verbose: false
    stages: [commit]

I tested this using the following steps:

  • stage a file (e.g. a simple txt file with modified content)
  • write a simple commit message like "this should be rejected"
  • commit the change
  • The failure message of my hook is displayed as expected
  • modify the commit message to "[PRO-1234] this should be accepted"
  • commit the change again without unstaging and staging the change
  • The commit is still rejected and printing the content of COMMIT_EDITMSG shows the previously (correctly) rejected message instead of my updated one

At first I thought that this is related to using SourceTree but I can try to commit using the git bash with the command git commit -m [either first or second message in double quotes] and get the same result

I was able to find multiple questions on the topic "git commit hooks" and also some sample scripts on git hub. I've read the git documentation about hooks as well but either my understanding on how this file COMMIT_EDITMSG is supposed to work is wrong or there is something going on I don't understand

anthony sottile
  • 61,815
  • 15
  • 148
  • 207
alaeX
  • 21
  • 2

1 Answers1

1

ah you've got a few things that are making this fail

first is that you've set stages: [commit] but you actually want stages: [commit-msg] (afterwards you'll need to pre-commit install --hook-type commit-msg (as documented))

second is that you've hardcoded the commit message filename -- while it's usually the one you've selected it isn't always that. you've also set pass_filenames: false which prevents pre-commit from telling your script about the actual commit message filename. so swap the hardcoded for sys.argv[1] and remove pass_filenames: false

putting that all together you should have something like:

repos:
- repo: local
  hooks:
  - id: commit-msg
    name: Enforce commit strategy
    description: make sure an epic id is correctly mentioned in the commit message
    entry: python commit-msg.py
    language: system
    stages: [commit-msg]

and

import sys
msg_temp_file = sys.argv[1]

# ...

disclaimer: I wrote pre-commit

anthony sottile
  • 61,815
  • 15
  • 148
  • 207
  • The commit message (file) is not being passed as an argument to the script, this is what I get when I run your suggestion ``` ./commit-msg.py", line 2, in msg_temp_file = sys.argv[1] ~~~~~~~~^^^ IndexError: list index out of range ``` – caverac Aug 21 '23 at 21:22
  • 1
    @caverac then you must have `pass_filenames: false` -- which... yeah I don't have to tell you what that does – anthony sottile Aug 21 '23 at 21:45
  • Thanks Anthony, that fixed the problem – caverac Aug 22 '23 at 16:36