Git预提交钩子调用PowerShell报错:Access to the path is Denied求助
问题场景
我为公司开发了一套Git预提交钩子,结构如下:
.git/hooks/pre-commit(Shell脚本):负责调用同目录下的pre-commit.ps1.git/hooks/pre-commit.ps1(PowerShell脚本):检查提交文件是否包含公司专属标识符
本地运行完全正常,但同事执行提交时触发错误:
Access to the path is denied. + CategoryInfo : ObjectNotFound: (:String) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : CommandNotFoundException
即使把pre-commit.ps1简化为仅输出Write-Host "Hello",错误依然存在,确认问题出在Shell脚本对PowerShell的调用环节。
已确认的信息:
- 同事已安装PowerShell
- 同事的
Get-ExecutionPolicy设置为Bypass,和我一致 - 同事的PowerShell起始目录是
C:\Windows\System32\,我的是H:(不确定是否相关)
pre-commit的Shell代码如下:
#!/bin/sh # Get the directory where the script is located HOOK_DIR=$(dirname "$0") # Use 'which' to find the PowerShell executable in the PATH POWERSHELL_PATH=$(which powershell.exe || which pwsh) # Check if PowerShell was found if [ -z "$POWERSHELL_PATH" ]; then echo "PowerShell not found in PATH" exit 1 fi # Invoke the PowerShell script using the dynamically found path "$POWERSHELL_PATH" -ExecutionPolicy ByPass -NoProfile -File "$HOOK_DIR/pre-commit.ps1"
排查与解决方案
1. 修复路径格式不兼容问题
Windows下Git默认使用Git Bash(基于MinGW),dirname "$0"返回的是类Unix格式路径(比如/.git/hooks),PowerShell无法识别这种格式导致路径访问被拒绝。修改路径转换逻辑:
HOOK_DIR=$(dirname "$0") # 将类Unix路径转为Windows兼容格式 HOOK_DIR_WIN=$(cmd //c echo "$HOOK_DIR" | sed 's/\//\\/g')
调用PowerShell脚本时使用转换后的路径:
"$POWERSHELL_PATH" -ExecutionPolicy ByPass -NoProfile -File "$HOOK_DIR_WIN/pre-commit.ps1"
2. 跳过which直接指定PowerShell路径
which在Git Bash中返回的路径可能存在权限或解析问题,直接指定绝对路径避免不确定性:
# Windows PowerShell 默认路径 POWERSHELL_PATH="/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe" # 若使用PowerShell Core,替换为以下路径 # POWERSHELL_PATH="/c/Program Files/PowerShell/7/pwsh.exe"
3. 确保钩子文件有可执行权限
在同事的Git Bash中执行以下命令,给pre-commit添加可执行标记:
chmod +x .git/hooks/pre-commit
4. 处理路径空格问题
如果项目路径包含空格,需确保路径被正确转义包裹,修改调用命令为:
"$POWERSHELL_PATH" -ExecutionPolicy ByPass -NoProfile -File "\"$HOOK_DIR_WIN/pre-commit.ps1\""
5. 测试基础PowerShell调用
让同事在Git Bash中直接执行以下命令,验证PowerShell是否能正常响应:
powershell.exe -ExecutionPolicy Bypass -NoProfile -Command "Write-Host 'Hello'"
如果此命令也报错,说明是PowerShell在Git Bash中的全局调用问题,需检查系统PATH配置或是否存在UAC权限拦截。
内容的提问来源于stack exchange,提问作者aishraq

