将PowerShell脚本作为git钩子运行

Eri*_*k T 31 git powershell githooks

是否可以将PowerShell脚本作为git钩子运行?

我在PowerShell提示符下运行git,这应该没什么区别,但是我似乎无法让它们工作,因为钩子的命名没有扩展,而PowerShell需要(AFAIK).ps1扩展名.我不确定这是问题还是其他问题.

谢谢,埃里克

Kim*_*Won 20

将pre-commit.sample重命名为hooks文件夹中的pre-commit.然后在同一文件夹中生成pre-commit.ps1 powershell脚本文件.

#!/bin/sh
c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -ExecutionPolicy RemoteSigned -Command -File '.git\hooks\pre-commit.ps1'
Run Code Online (Sandbox Code Playgroud)

  • 我认为这个命令行中的语法在-Command之后是错误的,它期望一个内联的PowerShell命令,但你也指定了一个文件.它将引发一个错误 - 文件未被识别为cmdlet,函数或脚本文件的名称. (2认同)

Kei*_*ill 16

您可以直接在钩子文件中嵌入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
Run Code Online (Sandbox Code Playgroud)

这个例子需要PowerShell Core,但结果它将运行跨平台(假设这个文件在Linux/macOS上是chmod + x).

  • 从2018年10月开始,这应该是公认的答案。谢谢基思。 (2认同)
  • 好答案!这个#!/ usr / bin / env pwsh技巧也可以用于git rebase --exec和git bisect run。不幸的是,我注意到当脚本失败时,`pwsh`不会退出并显示错误代码,因此请确保在某些情况下,将脚本更改为使用`exit`关键字。 (2认同)
  • 这个解决方案似乎不适用于我-`/ usr / bin / env:'pwsh':没有这样的文件或目录,并且我已经安装了powershell核心 (2认同)
  • 非常感谢!如果你想为了速度而在没有配置文件的情况下运行 Powershell(我确实这样做了),你可以在第一行执行此操作:`#!/usr/bin/env -S pwsh -NoProfile` (2认同)
  • 不幸的是,自 powershell 7.2 起,脚本在 Windows 上必须具有 .ps1 扩展名 (https://github.com/PowerShell/PowerShell/releases/tag/v7.2.0-preview.9)。需要像下面的一些答案这样的包装脚本。 (2认同)
  • 是的,那很令人失望。:-( (2认同)

Joe*_*oey 6

从我收集的内容来看,由于Git的设计,唯一的选择是调用PowerShell的bash脚本.不幸的是,但是Git并没有考虑非兼容性.

  • 自 2018 年 10 月起,您可以在预提交挂钩中直接使用 Powershell Core,如 Keith Hill 所详述。生活很好。请考虑更改已接受的答案。 (3认同)
  • 如果您正在寻找不同的、可能更好的答案来让您直接使用 Powershell Core,请参阅我对这个问题的回答。自从提出/回答这个问题以来,世界已经发生了变化,现在做到这一点几乎“太”容易了。 (2认同)

No *_*rns 6

这是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
}
Run Code Online (Sandbox Code Playgroud)

我还应该提到我在我的所有存储库中共享一个钩子副本。我的存储库都位于 R:\Git 中,我创建了 R:\Git\Hooks 并在全球范围内使用了https://git-scm.com/docs/githooksgit config core.hooksPath=R:\Git\Hooks。生活很好。


Tie*_*anO 5

我一直在寻找这个,我发现了以下内容:

Git Powershell预提交钩子(来源)

## Editor's note: Link is dead as of 2014-5-2.  If you have a copy, please add it.
Run Code Online (Sandbox Code Playgroud)

在PowerShell(Soure)中检查git pre-commit的PHP语法

##############################################################################
#
# 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
Run Code Online (Sandbox Code Playgroud)

代码用于预提交挂钩,但您可以修改它以执行任何操作.应该帮助你做你需要做的事情!


Tar*_*ran 5

Kim Ki Won上面的答案对我来说不起作用,但是它具有投票权,因此我认为它对某些人有用。

对我有用的是删除bin / sh,而不是使用-File执行,而是直接执行命令:

c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -ExecutionPolicy RemoteSigned -Command .\.git\hooks\pre-commit.ps1
Run Code Online (Sandbox Code Playgroud)


Sim*_*wsi 5

为了完整起见:

如果您只安装了 Windows PowerShell 而没有安装 PowerShell Core,那么 Keith Hill 的简洁回答将不起作用。使用 bash 脚本运行 PowerShell 的各种答案,传入要运行的 PowerShell 脚本的路径,很简单,也是我最终选择的方式。但是,我发现还有另一种方法:

为 git hook 创建两个文件,比如 pre-commit 和 pre-commit.ps1。pre-commit.ps1 文件是 PowerShell 将运行的文件。除了第一行的 PowerShell 解释器指令外,另一个预提交文件(没有文件扩展名)是空的:

#!/usr/bin/env powershell
Run Code Online (Sandbox Code Playgroud)

Git 将运行预提交文件,解析 PowerShell 解释器指令并运行 PowerShell,传入预提交文件的路径。PowerShell 将假定传入的文件应具有“.ps1”扩展名。它将搜索 pre-commit.ps1,并且由于您创建了具有该名称和扩展名的文件,PowerShell 将找到它并运行它。

这种方法既好又简单,但最终我决定反对它,因为它看起来有点“神奇”,可能会让维护者对其工作原理感到摸不着头脑。