How do I prompt the user from within a commit-msg hook?

Calling exec < /dev/tty assigns standard input to the keyboard. Works for me in a post-commit git hook:

#!/bin/sh

echo "[post-commit hook] Commit done!"

# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty

while true; do
  read -p "[post-commit hook] Check for outdated gems? (Y/n) " yn
  if [ "$yn" = "" ]; then
    yn='Y'
  fi
  case $yn in
      [Yy] ) bundle outdated --pre; break;;
      [Nn] ) exit;;
      * ) echo "Please answer y or n for yes or no.";;
  esac
done

The commit-msg hook is not run in an interactive environment (as you have noticed).

The only way to reliable notify the user would be to write an error to stdout, place a copy of the commit message in a BAD_MSG file and instruct the user to edit the file and git commit --file=BAD_MSG


If you have some control over the environment you could have an alternate editor which is a wrapper script that checks the proposed message, and can restart the editor with an extra commented message.

Basically, you run the editor, check the file saved against your rules. and if it fails, prepend your warning message (with leading #) to the file and restart the editor.

You could even allow them to put in a #FORCE=true line in the message which would suppress the check and continue.


this works fine when running git commit from command line. On windows (haven't tryed on linux) if you use gitk or git-gui you won't be able to prompt because you get an error on the "exec < /dev/tty" line.

The sollution is to call git-bash.exe in your hook:

.git/hooks/post-commit contains:

#!/bin/sh
exec /c/Program\ Files/Git/git-bash.exe /path/to/my_repo/.git/hooks/post-checkout.sh

the .git/hooks/post-commit.sh file contains:

# --------------------------------------------------------
# usage: f_askContinue "my question ?"
function f_askContinue {
  local myQuestion=$1

  while true; do
     read -p "${myQuestion} " -n 1 -r answer
     case $answer in
        [Yy]* ) printf "\nOK\n"; break;;
        [Nn]* )   printf "\nAbandon\n";
                  exit;;
        * ) printf "\nAnswer with Yes or No.\n";;
     esac
  done
}

f_askContinue "Do you want to continue ?"
echo "This command is executed after the prompt !"