4

I'm aborting git commit if a certain condition is met.

check if my commit has 'import pdb' in emacs/git?

#!/bin/sh

git diff --cached --no-renames --name-status --diff-filter=AM |
  while read st file; do
    case "$file" in
    *.py)
        if git show ":$file" |
          grep -E "^[^#]*\bimport[[:space:]]+pdb\b"; then
            echo "$file: has import pdb"
            exit 1
        fi;;
    esac
done

git diff --cached --name-status --diff-filter=ACM | while read st file; do
    if grep "#[[:space:]]*@test" "$file"; then
        echo "$file: has @test"
        exit 1
    fi
done

The code runs fine and I can see the log "... has import pdb" But the next line exit 1 won't abort the git commit.

It used to work fine, but it stopped working at some point. I'm on git 1.9.1


output

$ GIT_TRACE=2 git commit
trace: built-in: git 'commit'
trace: run_command: '.git/hooks/pre-commit'
trace: built-in: git 'diff' '--cached' '--no-renames' '--name-status' '--diff-filter=AM'
trace: built-in: git 'show' ':momsite/apps/custom_push_notifications/utils.py'
    import pdb; pdb.set_trace()
momsite/apps/custom_push_notifications/utils.py: has import pdb
trace: built-in: git 'diff' '--cached' '--name-status' '--diff-filter=ACM'
trace: run_command: 'emacs' '/home/eugenekim/Documents/zibann/.git/COMMIT_EDITMSG'
trace: exec: 'emacs' '/home/eugenekim/Documents/zibann/.git/COMMIT_EDITMSG'
Community
  • 1
  • 1
eugene
  • 39,839
  • 68
  • 255
  • 489
  • Please, make your questions self-contained, or use the comments in the question you link to to improve the answer there. Also, can you post your exact script and the exact commands you ran? Otherwise, we can't debug your problem ... – Matthieu Moy Apr 30 '15 at 14:08
  • @MatthieuMoy right.. I added the code. – eugene Apr 30 '15 at 14:13
  • Can you add the exact command you ran? Also, you can try running `GIT_TRACE=2 git commit` and see the output. – Matthieu Moy Apr 30 '15 at 14:23
  • I added the output of `git_trace=2 git commit`. as you can see the pre-commit hook runs fine, but just keeps going regardless of the `exit 1` – eugene Apr 30 '15 at 15:09
  • You have also changed the code, and now I understand why it does not work. – Matthieu Moy Apr 30 '15 at 15:56

1 Answers1

4

The first part of the code reads like

something | while ...; do ... exit 1; done

Since a pipe necessarily involves two processes, the shell has to fork a subshell to execute your while loop. As a result, exit 1 exists from the subshell with status 1, and returns to your parent shell, which ignores the return code.

You want to add a || exit $? after the done keyword, like this:

something | while ...; do ... exit 1; done || exit $?

Note that this is not actually a Git question, but a shell issue.

Matthieu Moy
  • 15,151
  • 5
  • 38
  • 65