是否可以将 PowerShell 脚本作为 git 挂钩运行?
我在 PowerShell 提示符下运行 git,这应该没有任何区别,但我似乎无法让它们工作,因为挂钩的命名没有扩展名,并且 PowerShell 需要(AFAIK).ps1 扩展名。我不确定这是问题所在,还是其他问题。
是否可以将 PowerShell 脚本作为 git 挂钩运行?
我在 PowerShell 提示符下运行 git,这应该没有任何区别,但我似乎无法让它们工作,因为挂钩的命名没有扩展名,并且 PowerShell 需要(AFAIK).ps1 扩展名。我不确定这是问题所在,还是其他问题。
您可以将 PowerShell 脚本直接嵌入到挂钩文件中。pre-commit
这是我使用的钩子的示例:
#!/usr/bin/env pwsh
# Verify user's Git config has appropriate email address
if ($env:GIT_AUTHOR_EMAIL -notmatch '@(non\.)?acme\.com$') {
Write-Warning "Your Git email address '$env:GIT_AUTHOR_EMAIL' is not configured correctly."
Write-Warning "It should end with '@acme.com' or '@non.acme.com'."
Write-Warning "Use the command: 'git config --global user.email <name@acme.com>' to set it correctly."
exit 1
}
exit 0
此示例需要 PowerShell Core,但因此它将跨平台运行(假设此文件在 Linux/macOS 上为 chmod +x)。
在 hooks 文件夹中将 pre-commit.sample 重命名为 pre-commit。然后在同一文件夹中制作 pre-commit.ps1 powershell 脚本文件。
#!/bin/sh
c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -ExecutionPolicy RemoteSigned -File '.git\hooks\pre-commit.ps1'
由于 Git 的设计,我收集到的唯一选择是调用 PowerShell 的 bash 脚本。不幸的是,但话又说回来,Git 并没有考虑到非 Linux 的兼容性。
Kim Ki Won
上面的答案对我不起作用,但它有赞成票,所以我认为它适用于某些人。
对我有用的是删除 bin/sh 而不是使用 -File 执行,而是直接执行命令:
c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -ExecutionPolicy RemoteSigned -Command .\.git\hooks\pre-commit.ps1
这是我在PowerShell Git Hooks
阅读 Keith Hill 的回答后一直在使用的起始 PWSH 脚本。非常好。
#!/usr/bin/env pwsh
Process {
Write-Information -MessageData "I Ran" -InformationAction Continue
}
Begin {
Write-Information -MessageData "Beginning" -InformationAction Continue
}
End {
Write-Information -MessageData "Ending" -InformationAction Continue
Exit 0
}
我还应该提到我在我的所有存储库中共享一个钩子副本。我的存储库都位于 R:\Git 中,我创建了 R:\Git\Hooks 并在全球范围内使用了https://git-scm.com/docs/githooks 。git config core.hooksPath=R:\Git\Hooks
生活很好。
为了完整起见:
如果您只安装了 Windows PowerShell 而没有安装 PowerShell Core,那么 Keith Hill 的简洁答案将不起作用。使用 bash 脚本运行 PowerShell、传递要运行的 PowerShell 脚本的路径的各种答案都是直截了当的,也是我最终选择的方式。但是,我发现还有另一种方法:
为 git 钩子创建两个文件,比如 pre-commit 和 pre-commit.ps1。pre-commit.ps1 文件是 PowerShell 将运行的文件。除了第一行的 PowerShell 解释器指令外,另一个预提交文件(没有文件扩展名)是空的:
#!/usr/bin/env powershell
Git 将运行预提交文件,解析 PowerShell 解释器指令并运行 PowerShell,并传入预提交文件的路径。PowerShell 将假定传入的文件应具有“.ps1”扩展名。它将搜索 pre-commit.ps1,并且由于您创建了具有该名称和扩展名的文件,PowerShell 将找到并运行它。
这种方法既好又简单,但最后我决定反对它,因为它看起来有点“神奇”,并且可能会让维护者对它的工作原理摸不着头脑。
我自己一直在寻找这个,我发现了以下内容:
Git Powershell 预提交钩子(来源)
## Editor's note: Link is dead as of 2014-5-2. If you have a copy, please add it.
PowerShell 中 git 预提交的 PHP 语法检查(Soure)
##############################################################################
#
# PHP Syntax Check for Git pre-commit hook for Windows PowerShell
#
# Author: Vojtech Kusy <wojtha@gmail.com>
#
###############################################################################
### INSTRUCTIONS ###
# Place the code to file "pre-commit" (no extension) and add it to the one of
# the following locations:
# 1) Repository hooks folder - C:\Path\To\Repository\.git\hooks
# 2) User profile template - C:\Users\<USER>\.git\templates\hooks
# 3) Global shared templates - C:\Program Files (x86)\Git\share\git-core\templates\hooks
#
# The hooks from user profile or from shared templates are copied from there
# each time you create or clone new repository.
### SETTINGS ###
# Path to the php.exe
$php_exe = "C:\Program Files (x86)\Zend\ZendServer\bin\php.exe";
# Extensions of the PHP files
$php_ext = "php|engine|theme|install|inc|module|test"
# Flag, if set to 1 git will unstage all files with errors, se to 0 to disable
$unstage_on_error = 0;
### FUNCTIONS ###
function php_syntax_check {
param([string]$php_bin, [string]$extensions, [int]$reset)
$err_counter = 0;
write-host "Pre-commit PHP syntax check:" -foregroundcolor "white"
git diff-index --name-only --cached HEAD -- | foreach {
if ($_ -match ".*\.($extensions)$") {
$file = $matches[0];
$errors = & $php_bin -l $file
if ($errors -match "No syntax errors detected in $file") {
write-host $file ": OK" -foregroundcolor "green"
}
else {
write-host $file ":" $errors -foregroundcolor "red"
if ($reset) {
git reset -q HEAD $file
write-host "Unstaging" $file "..." -foregroundcolor "magenta"
}
$err_counter++
}
}
}
if ($err_counter -gt 0) {
exit 1
}
}
### MAIN ###
php_syntax_check $php_exe $php_ext $unstage_on_error
该代码用于预提交挂钩,但您可以对其进行修改以执行几乎任何操作。应该帮助你需要做的事情!
这是我在 Windows 上的 git 钩子,位于 .\git\hooks 中。
更新后
#!/bin/sh
c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -ExecutionPolicy Bypass -Command '.\post-update.ps1'
位于项目根文件夹(最初运行 git init 的位置)中的 Powershell 脚本。Powershell 转到另一个存储库并调用 pull,更新该存储库。
更新后.ps1
Set-Location "E:\Websites\my_site_test"
$env:GIT_DIR = 'E:\Websites\my_site_test\.git';
$env:GIT_EXEC_PATH= 'C:\Program Files (x86)\Git/libexec/git-core';
git pull
我没有得到西蒙的回答,可能是因为我的路径中的其他东西没有被 windows git 环境和/或使用 bonobo git 服务器正确解析。
我的目标是为托管在 bonobo 中的存储库编写一个预接收挂钩。
我最终得到了以下shebang:
#!/c/Windows/System32/WindowsPowerShell/v1.0/powershell
否则工作方式相同:
就我而言,为了保持清洁,我也使用了
mklink <path-to-repo>\hooks\pre-receive.ps1 c:\scripts\hooks\someLibraryScript.ps1
当然,这允许我将脚本保存在中央存储库中。
编辑:值得注意的是,我没有设法让 Powershell 接受预接收挂钩的标准输入流。结果,我仍在使用 shell 脚本来引导 powershell 和管道,而不是将标准输入重定向到 powershell。
在这种情况下,我为我的预接收挂钩使用了以下 shell 脚本:
#!/bin/sh
IFS=
echo `cat -` | powershell.exe -NoProfile -ExecutionPolicy Bypass -File "c:\scripts\hooks\pre-receive.ps1"
Powershell 似乎对此感到满意。
上面的许多答案都有很多年了,现在有更简单更好的选择。
在 Windows PowerShell 时代,无法使用#! /usr/bin/env powershell
,因为它不接受没有扩展名的文件。
解决方法是在目录中创建具有相同名称但扩展名为 的脚本文件.ps1
,这在其他人的答案中有所提及。但这利用了可能未记录的内部实现,并且可能会出现意想不到的问题。
但是,在 pwsh 时代,为了跨平台兼容,已经支持运行不带扩展名的脚本文件。即使在windows平台上,只需要添加#! /usr/bin/env pwsh
,就可以直接在该文件中编写脚本,无需任何其他额外操作。