与手动运行时相比,使用git运行时,echo -n的预提交钩子表现不同

时间:2017-04-19 11:03:07

标签: git bash pre-commit-hook

我已经编写了一个预提交钩子来检查我是否不小心使用制表符来缩进我的新代码。

我通过暂存各种更改并通过键入$ bash .git/hooks/pre-commit来模拟由git触发的挂钩来手动运行挂钩来开发它(我认为这是一个非常准确的环境)。但是,当它在提交期间实际上由git运行时,它的行为会有所不同。为什么是这样?

以下是bash脚本的简化示例:

#!/bin/sh

# Default to zero which means the changes are good and the commit can go ahead
exitstatus=0

# Grab the lines with the plus symbol and tab characters at the start (eg. New lines, indented wrongly)
tabbedlines=$( git diff --cached -U0 code/ | egrep "^\+\t" )

# Count the lines (** THIS IS THE BIT THAT BEHAVES DIFFERENTLY **)
tabbedlinecount=$( echo -n "$tabbedlines" | grep -c '^' )

if [ $tabbedlinecount -gt 0 ]
then
  exitstatus=1
fi

exit $exitstatus

基本上,这是以tabbedlinecount=...开头的行为不同的行。带有echo标志的-n在bash环境中运行时返回0,但在提交期间由git运行时返回1。我已经通过将其更改为使用printf来证明了这一点,而这种行为始终如一,从而解决了问题,但即使我已修复它,我仍然想了解原因?!

与我的终端使用的shell相比,这与git使用的shell有关吗?我现在有点超出我的深度。帮我堆栈溢出,你是我唯一的希望。

1 个答案:

答案 0 :(得分:2)

您的脚本使用#!/bin/sh。如果该shell为dash(或其他严格符合POSIX shell,则echo -n whatever的输出为

$ echo -n
-n

即,-n未被识别为禁止尾随换行符的选项。请改用printf

$ tabbedlinecount=$( printf '%s' "$tabbedlines" | grep -c '^' )