如何在commit-msg挂钩中提示用户?

Ben*_*ing 69 git hook commit-message

我想警告用户,如果他们的提交消息不遵循某组指南,然后给他们选项来编辑他们的提交消息,忽略警告或取消提交.问题是我似乎无法访问stdin.

下面是我的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
Run Code Online (Sandbox Code Playgroud)

当我将Scope信息留空时,这是输出:

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

消息是正确的,但它实际上并没有停止输入.我也尝试使用更简单的"读取"命令,它也有同样的问题.似乎问题在于,此时git控制了stdin并提供了自己的输入.我该如何解决?

更新:似乎这可能是这个问题的重复,不幸的是,这似乎表明我运气不好.

Eli*_*kes 146

调用exec < /dev/tty将标准输入分配给键盘.在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
Run Code Online (Sandbox Code Playgroud)

  • 可以使用`exec <& - `再次关闭STDIN (20认同)
  • 如果你正在使用Ruby,那就转换为`STDIN.reopen('/ dev/tty')`.很棒的东西,这才是真正的答案. (14认同)
  • 如果您使用的是Python,那么它将转换为`sys.stdin = open("/ dev/tty","r")`.可以帮助别人:) (9认同)
  • 这很棒,但是当从另一个工具(例如编辑器)提交时它可能会中断.不确定如何解决这个问题,但如果有人有想法,我会有兴趣听到. (4认同)
  • 这甚至适用于[MingW32](http://www.mingw.org/)(GNU-ish Windows层)下的`bash`.谢谢! (3认同)

Fro*_*sty 6

commit-msg钩子不是在一个互动的环境中运行(如你已经注意到).

可靠地通知用户的唯一方法是向stdout写入错误,将提交消息的副本放在BAD_MSG文件中并指示用户编辑文件和git commit --file=BAD_MSG


如果您对环境有一些控制权,则可以使用备用编辑器,该编辑器是一个检查建议消息的包装脚本,并且可以使用额外的注释消息重新启动编辑器.

基本上,您运行编辑器,检查根据您的规则保存的文件.如果失败,请将警告消息(带前导#)添加到文件中,然后重新启动编辑器.

您甚至可以允许他们#FORCE=true在消息中添加一行来抑制检查并继续.

  • 首先尝试在脚本中调用`exec </ dev/tty`以捕获用户输入 - 请参阅其他答案. (8认同)

Nic*_*hek 6

read -p "Question? [y|n] " -n 1 -r < /dev/tty
echo
if echo $REPLY | grep -E '^[Yy]$' > /dev/null; then
#do if Yes
else
#do if No
fi
Run Code Online (Sandbox Code Playgroud)