1. ホーム
  2. git

commit-msg フックの中からユーザーにプロンプトを出すにはどうすればよいですか?

2023-09-15 16:24:08

質問

私は、コミットメッセージが特定のガイドラインのセットに従っていない場合にユーザーに警告し、その後、コミットメッセージを編集するか、警告を無視するか、またはコミットをキャンセルするかのオプションを与えたいと思います。問題は、私が標準入力にアクセスできないようであることです。

以下は私の commit-msg ファイルです。

function verify_info {
    if [ -z "$(grep '$2:.*[a-zA-Z]' $1)" ]
    then
        echo >&2 $2 information should not be omitted
        local_editor=`git config --get core.editor`
        if [ -z "${local_editor}" ]
        then
            local_editor=${EDITOR}
        fi
        echo "Do you want to"
        select CHOICE in "edit the commit message" "ignore this warning" "cancel the commit"; do
            case ${CHOICE} in
                i*) echo "Warning ignored"
                    ;;
                e*) ${local_editor} $1
                    verify_info "$1" $2
                    ;;
                *)  echo "CHOICE = ${CHOICE}"
                    exit 1
                    ;;
            esac
        done
    fi
}

verify_info "$1" "Scope"
if [ $# -ne 0 ];
then
    exit $#
fi
verify_info "$1" "Affects"
if [ $# -ne 0 ];
then
    exit $#
fi

exit 0

Scope情報を空白にした場合の出力は以下の通りです。

Scope information should not be omitted
Do you want to:
1) edit the commit message  3) cancel the commit
2) ignore this warning
#?

メッセージは正しいのですが、実際に入力のために停止することはありません。もっと単純な "read" コマンドも使ってみましたが、同じ問題がありました。どうやら、この時点で git が標準入力を制御して、自分自身の入力を提供していることが問題のようです。どうすればこれを修正できますか?

更新: どうやらこれは この質問 と重複している可能性があり、残念ながら私は運が悪いと思われます。

どのように解決するのですか?

呼び出し exec < /dev/tty を呼び出すと、標準入力がキーボードに割り当てられます。コミット後の git フックで動作します。

#!/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