After finding out about hooks in git a while ago I always thought it would be a good idea to set one up and add something like basic linting or maybe something to do with auto creating / updating markdown files.  I never bothered to actually get something working until today so thought i would share. This is a really simple example where i use the PSScriptingAnalyzer to check my code is following its basic linting rules. I use git diff to find the files that have been changed and run Invoke-ScriptAnalyzer against them. If there are any issues then the commit fails.

What is a pre-commit hook in git

To put it simply, its code that is run BEFORE committing your code to your local repo.

How to set up a pre-commit hook in git

Create Pre-commit files

First go into your git repo .git\hooks (In Windows you will need to see hidden files / folders) in my example I have a root folder called Github and my repo is called Blog. In here you will see a collection of samples. As you can see there are options to hook into a lot of different commands.

pre-commit02

Create 2 new files:

  • pre-commit (No file extension)
  • pre-commit.ps1

We should end up with the below:

pre-commit01

Update the pre-commit files

In the pre-commit add the following text:

#!/bin/sh
c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -ExecutionPolicy RemoteSigned -Command '.git\hooks\pre-commit.ps1'

This is the file called by Git when a pre-commit action occurs and it simply tells git to run a powershell file.

In the pre-commit.ps1 file add:

As i said early this script just uses git diff to list out the files that have changed and runs Invoke-ScriptAnalyzer against them. If there are any issues. It exits with a failure and the commit is rolled backed. If there are no issues then the commit is successful.

Test Pre-Commit

Now lets test that our pre-commit code works!

Create a new file and add some code that will break a ScriptAnalyzer (below is my example):

function myfunction  {
    param (
        [string]$text
    )

    [int]$test
    write-host "You wrote: $text"
}

now do a commit and you should see something like:
pre-commit03

If you go back and update the script to use Write-Output instead of Write-Host your should see something like:

pre-commit04

Summary

And there we have it. A pre-commit using powershell.. Pretty simple to set up. But there are still some bugs to fix. If you try using this VS Code you wont get the correct output for some reason (Hopefully I can update that later with a fix!) but for now i hope this helps people get started.

Advertisements