将 PowerShell 脚本作为 git hook 运行
是否可以将 PowerShell 脚本作为 git hook 运行?
我在 PowerShell 提示符下运行 git,这应该没有任何区别,但我似乎无法让它们工作,因为钩子的命名没有扩展名,并且 PowerShell 需要(据我所知).ps1 扩展名。我不确定这是问题还是其他问题。
Is it possible to run PowerShell scripts as git hooks?
I am running git in a PowerShell prompt, which shouldn't make any difference, but I can't seem to get them to work, as the hooks are named without extensions, and PowerShell needs (AFAIK) the .ps1 extension. I am not sure if that is the issue, or something else.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
自 powershell 7.2 起,脚本必须具有 .ps1 扩展名视窗。所以这个答案不会起作用。
您可以将 PowerShell 脚本直接嵌入到挂钩文件中。以下是我使用过的
pre-commit
挂钩示例:此示例需要 PowerShell Core,但因此它将跨平台运行(假设此文件已在 Linux/macOS 上 chmod +x )。
Since powershell 7.2 the script must have .ps1 extension on Windows. So this answer will not work.
You can embed PowerShell script directly inside the hook file. Here is an example of a
pre-commit
hook I've used:This example requires PowerShell Core but as a result it will run cross-platform (assuming this file has been chmod +x on Linux/macOS).
将 pre-commit.sample 重命名为 hooks 文件夹中的预提交。
然后在同一文件夹中制作 pre-commit.ps1 powershell 脚本文件。
Rename pre-commit.sample to pre-commit in hooks folder.
Then make pre-commit.ps1 powershell script file in same folder.
Kim Ki Won
的上述答案对我来说不起作用,但它得到了赞成票,所以我假设它对某些人有用。对我有用的是删除 bin/sh ,而不是使用 -File 执行,而是直接执行命令:
Kim Ki Won
's answer above didn't work for me, but it has upvotes so I'll assume it works for some people.What worked for me was dropping the bin/sh and instead of executing using -File, executing the command directly:
这是一个起始 PWSH 脚本,自从阅读 Keith Hill 的回答以来,我一直将其用于我的
PowerShell Git Hooks
。很不错。我还应该提到我在所有存储库中共享一个钩子副本。我的存储库全部位于 R:\Git 中,我创建了 R:\Git\Hooks 并使用 https://git -scm.com/docs/githooks 到全局 git config core.hooksPath=R:\Git\Hooks 。生活是美好的。
Here's a starting PWSH script that I've been using for my
PowerShell Git Hooks
since reading Keith Hill's answer. Very nice.I should also mention I share a single copy of hooks across all my repos. My repos all live in R:\Git and I created R:\Git\Hooks and used https://git-scm.com/docs/githooks to
git config core.hooksPath=R:\Git\Hooks
globally. Life is good.为了完整起见:
如果您只安装了 Windows PowerShell 而没有安装 PowerShell Core,那么 Keith Hill 的简洁答案不起作用。使用 bash 脚本运行 PowerShell、传入要运行的 PowerShell 脚本的路径的各种答案都很简单,也是我最终选择的方式。但是,我发现还有另一种方法:
为 git hook 创建两个文件,例如 pre-commit 和 pre-commit.ps1。 pre-commit.ps1 文件是 PowerShell 将运行的文件。另一个预提交文件(没有文件扩展名)除了第一行的 PowerShell 解释器指令之外是空的:
Git 将运行预提交文件,解析 PowerShell 解释器指令并运行 PowerShell,将路径传递给预提交文件。 PowerShell 将假定传入的文件应具有“.ps1”扩展名。它将搜索 pre-commit.ps1,并且由于您创建了具有该名称和扩展名的文件,PowerShell 将找到它并运行它。
这种方法很好也很简单,但最终我决定反对它,因为它看起来有点“神奇”,并且可能会让维护人员对其工作原理摸不着头脑。
For the sake of completeness:
If you only have Windows PowerShell and not PowerShell Core installed then Keith Hill's neat answer doesn't work. The various answers that use a bash script to run PowerShell, passing in the path to the PowerShell script to run, are straight-forward and the way I chose to go in the end. However, I discovered there is another way:
Create two files for the git hook, say pre-commit and pre-commit.ps1. The pre-commit.ps1 file is the file that PowerShell will run. The other pre-commit file (without a file extension) is empty apart from a PowerShell interpreter directive on the first line:
Git will run the pre-commit file, parse the PowerShell interpreter directive and run up PowerShell, passing in the path to the pre-commit file. PowerShell will assume the file passed in should have a ".ps1" extension. It will search for pre-commit.ps1 and, since you created a file with that name and extension, PowerShell will find it and run it.
This approach is nice and simple but, in the end, I decided against it because it seemed a little "magical" and might have maintainers scratching their heads about how it works.
据我所知,由于 Git 的设计,唯一的选择是调用 PowerShell 的 bash 脚本。不幸的是,Git 并没有考虑到非 Linux 兼容性。
From what I gather the only option due to Git's design here would be a bash script calling PowerShell. Unfortunate, but then again, Git didn't place any thought on non-Linux compatibility.
我自己一直在寻找这个,我发现了以下内容:
Git Powershell pre-commit hook (来源)
PowerShell 中 git 预提交的 PHP 语法检查 (Soure< /a>)
该代码用于预提交挂钩,但您可以修改它以执行几乎任何操作。应该对你需要做的事情有所帮助!
I have been looking for this myself, and i found the following:
Git Powershell pre-commit hook (Source)
PHP Syntax check for git pre-commit in PowerShell (Soure)
The code is for a pre-commit hook, but you could modify it to do pretty much anything. Should help what you need to do!
这是我在 Windows 上的 git hook,位于 .\git\hooks。
更新后
Powershell 脚本位于项目根文件夹(您最初运行 git init 的位置)。 Powershell 转到另一个存储库并调用 pull,更新该存储库。
更新后.ps1
This is my git hook on Windows located in .\git\hooks.
post-update
Powershell script located in the project root folder (where you initially run git init). Powershell goes to another repository and calls pull, updating that repository.
post-update.ps1
新时代更好的 pwsh 解决方案
上面的许多答案已经有很多年了,现在有更简单、更好的选择。
在 Windows PowerShell 时代,不可能使用
#! /usr/bin/env powershell
,因为它不接受没有扩展名的文件。解决方法是在目录中创建同名但扩展名为
.ps1
的脚本文件,这在其他人的答案中提到过。但这利用了可能的未记录的内部实现,并且可能会出现意想不到的问题。不过到了pwsh时代,已经支持运行不带扩展名的脚本文件,以实现跨平台兼容。即使在windows平台上,也只需要添加
#即可! /usr/bin/env pwsh
,您可以直接在该文件中编写脚本,无需任何其他额外操作。Better solutions for pwsh in the new era
Many of the answers above are many years old, and there are now simpler and better options.
In the days of Windows PowerShell, it was not possible to use
#! /usr/bin/env powershell
, because it did not accept files without extensions.The workaround was to create script files in the directory with the same name but with the extension
.ps1
, which was mentioned in someone else's answer. But this takes advantage of a possible undocumented internal implementation, and unexpected problems may occur.However, in the pwsh era, running script files without extensions has been supported for cross-platform compatibility. Even on windows platforms, it is only necessary to add
#! /usr/bin/env pwsh
, you can write scripts directly in this file without any other additional actions.我没有得到西蒙的答案,可能是因为我的路径中的其他东西没有被 Windows git 环境和/或使用 bonobo git 服务器正确解析。
我的目标是为 bonobo 托管的存储库编写一个预接收挂钩。
我最终得到以下 shebang:
否则工作方式相同:
就我而言,为了保持清洁,我还使用了
这当然可以让我将脚本保存在中央存储库中。
编辑:值得注意的是,我没有设法让 Powershell 接受预接收挂钩的标准输入流。因此,我仍然使用 shell 脚本来引导 powershell 和管道,而不是将 stdin 重定向到 powershell。
在本例中,我使用以下 shell 脚本作为我的预接收挂钩:
Powershell 似乎对此感到满意。
I didn't get Simon's answer to work, potentially because of other things in my path not being parsed properly by the windows git environment and/or using bonobo git server.
My objective was writing a pre-receive hook for a repository hosted in bonobo.
I ended up with the following shebang:
Otherwise works identically:
In my case, for some cleanliness, i also used
This allows me to keep my scripts in a central repository, of course.
EDIT: It's worth noting i did not manage to get Powershell to accept the stdin stream for the pre-receive hook. As a result, i'm still using a shell script to bootstrap powershell and pipe, rather than redirect, stdin to powershell.
In this case, i used the following shell script for my pre-receive hook:
Powershell seems satisfied with that.