Bash git-hook在Linux上正常运行,但在Mac上失败

问题描述

我正在尝试为prepare-commit-msg编写我的第一个git钩子,我将其放在一起,其行为完全符合我在Fedora盒上的期望:

#!/usr/bin/bash
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3
TRELLO_ID='XXX' # our trello project id
branchName=`git rev-parse --abbrev-ref HEAD`
IFS=/ read commitType issueNumber commitDesc <<< $(echo $branchName)
if [[ -z $issueNumber ]]; then
  exit 1
fi
firstLine=$(head -n1 $1)
if [ -z "$firstLine"  ] ;then #Check that this is not an amend by checking that the first line is empty
        sed -i'.bak' -e "1s/^/Issue $issueNumber: \n/" $COMMIT_MSG_FILE
        sed -i'.bak' -e "2a\
                Issue link: https://trello.com/c/$TRELLO_ID/$issueNumber \n" $COMMIT_MSG_FILE
fi

我已经与在Mac上运行的团队成员分享了此信息,但此操作一直失败。有关mac设置的额外信息是它正在运行zsh,但我不知道这是否相关。我对Mac不熟悉,因此我无法帮助其他人在运行git commit时在此文件中回显很多东西。出于记录,我对bash的使用也不是很熟练。

起初,我以为这是sed兼容性的问题,因为我在这里发现的其他问题都围绕着它,但是经过进一步测试,看来在拆分分支名称时这已经失败了(我们使用约定{{ 1}})。我还注意到在文件周围使用单引号和双引号的语法中的一些重要性。

最后一个好奇,如果我们在他的终端上运行<type>/<ticket-number>/<desc>,在他的Mac上,我们会得到$ which bash,这是否意味着shebang也是错误的?人们如何保持这样的脚本在Linux和Mac之间具有如此多的小细节兼容?我还考虑过在python上重写它,这可能会带来更容易的兼容性,但我真的很想了解在两个系统上都可以进行此工作的必要条件。

谢谢!

解决方法

使用sh shebang编写类似的脚本,然后使用https://www.shellcheck.net/

进行检查

如果sh shebang一切正常,则意味着该脚本可以与任何版本的bash,zsh或任何POSIX shell解释器一起正常工作。 MacOS的BSD类型环境可能具有使用不同语法的工具或至少缺少GNU CoreUtils特定功能的工具,因此请谨慎在运行命令时不要使用这些特定选项。

#!/usr/bin/env sh

COMMIT_MSG_FILE="$1"
COMMIT_SOURCE="$2"
SHA1="$3"
TRELLO_ID='XXX' # our trello project id
branchName=$(git rev-parse --abbrev-ref HEAD)
IFS=/
# Split branchName at / into arguments
# shellcheck disable=SC2086 # intended word splitting
set -- $branchName
commitType="$1"
issueNumber="$2"
commitDesc="$3"
if [ -z "$issueNumber" ]; then
  exit 1
fi
firstLine=$(head -n1 "$COMMIT_MSG_FILE")
if [ -z "$firstLine"  ] ;then #Check that this is not an amend by checking that the first line is empty
        mv -- "$COMMIT_MSG_FILE" "$COMMIT_MSG_FILE.bak" &&
        sed -e "1s/^/Issue $issueNumber: \n/;2a\
                Issue link: https://trello.com/c/$TRELLO_ID/$issueNumber \n" "$COMMIT_MSG_FILE.bak" >"$COMMIT_MSG_FILE"
fi
,

我在Mac上也遇到过类似的情况,然后意识到我们也有Windows使用者。

不确定是否相关,但是,如果您具有javascript应用程序,则可以使用https://github.com/typicode/husky来制作钩子,方法有些不同。除了平台支持之外,还可以将此类挂钩提交到存储库中,从而消除了新手手动设置的需要。

对于使用其他语言实现的解决方案,可能还有其他类似的解决方案。