Wilson Mar bio photo

Wilson Mar

Hello. Join me!

Email me Calendar Skype call 310 320-7878

LinkedIn Twitter Gitter Google+ Youtube

Github Stackoverflow Pinterest

One commit and you’re hooked


Here is a tutorial on how to make Git on a local machine run a script automatically in response to git commands.

How Git Hooks work

Every Git repository is created with a hooks folder. Git looks into the .git/hooks folder for scripts when events occur.

PROTIP: In your GitHub repository, create a “hooks” folder containing script files that a new repo setup script copies into the .git/hooks folder.

  1. Navigate into any Git repository you want to automate.

    cd .git/hooks

    Each Git repository folder is created with a set of sample automation files.


    PROTIP: You may delete these sample files because I’ve added links to each file listed above to the source of the files at:


    These file names end with “.sample” so that they won’t run. This is because Git automatically runs files renamed with no file extension, such as “pre-commit” (renamed from “pre-commit.sample”). But most people edit the file when they rename to customize the action they want.

    PROTIP: A longer list is at Matthew Hudson’s githooks.com, along with projects others have done with hooks. The canonical documentation is at https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks

    Hooks by Event

    There are two types of hooks: client (on your laptor or server) and server (GitHub, GitLab, etc.).

    githooksgrid This illustration (by Sarah Goff-Dupont of Atlassian) identifies the most common uses.

    On the client

    On the client, upon git commit, the hooks are executed in this order:

    1. pre-commit (to run unit tests, look for console messages, etc.)
    2. prepare-commit-msg (add extra alerts)
    3. commit-msg (send email to collaborators)
    4. post-commit

    • pre-rebase is run before Git executes git rebase.
    • applypatch-msg is run before Git executes git patch.

    On the server

    1. pre-receive (code coverage)
    2. update
    3. post-receive (send email, run load tests)

The flow of processing is illustrated by this (from Johan Abildskov & Jan Krag of Praqma)
git hooks diagram 650x251(click for full screen image)

Before we get into manual instllation steps, you need to know that there are automated options available.

IntelliJ IDE Automation

IntelliJ IDEA from Jetbrains, the free Community Edition, provides check-boxes to activate Git hooks.

git intellij before commit 302x418-87kb

PROTIP: We don’t see how to get to Version Control in IntelliJ on videos because it’s often accessed via a hotkey - apple 9 on macs and Alt+9 on Windows.

See https://www.youtube.com/watch?v=V8KSaQKgR1Y for VCS improvements in IntelliJ 2016.3.

Let’s use a sample project that already has .idea folder containing files that define configurations for IntelliJ.

IntelliJ has a project wizard to start from scratch on various languages.

But Andrew Krug’s Java example also has integration with testing utilities.

One-liner to install and run

  1. Open a Terminal shell window to where you would like to add a script. One example on a Mac is a folder under your home directory, such as:


  2. Copy this script to your Clipboard and paste it on the Terminal command line.

    `sh -c "$(curl -fsSL https://raw.githubusercontent.com/wilsonmar/Basic-Selenium-Java/master/mac-bootstrap.sh)"`

    (Press Enter to run).

    The script downloadloads all pre-requisites before running the test.

    Step through the automation

  3. Use Finder to look at the repo.

    The target being developed/tested is the Java source code under folder /src/test/java/localbrowsers.

    Each “.java” program is a unit test to simply retrieve a website in a browser.

    The “memory-leak.java” source file intentionally creates a memory leak when run.

    The basic-selenium-java.iml file.

  4. Install internet browsers used by running the shell script:

    chmod +x mac_install_browsers.sh && ./mac_install_browsers.sh

    Installed are browser add-ins for testing (with cask being used for GUI apps). Links to websites have been added:

    • brew install geckodriver
    • brew cask install firefox
    • brew install chromedriver
    • brew cask install google-chrome
    • brew install phantomjs (a “headless” browser)
    • Safari doesn’t need to be installed because it comes with Apple Macs.

    If you get this error, rerun:

    curl: (56) SSLRead() return error -9806

  5. Use Finder to look at the pom.xml file specifying Java stuff to be downloaded:

    • org.seleniumhq.selenium
    • org.testng

    Maven plug-ins:

    • maven-surefire-plugin from http://maven.apache.org/components/surefire/maven-surefire-plugin/ to execute tests. https://www.youtube.com/watch?v=R2ok6mKU0TI

    • jacoco-maven-plugin (http://www.jacoco.org/) for determines code coverage. (It was written for running in Eclipse, but IntelliJ uses it too.)

    • coveralls-maven-plugin from https://github.com/trautonen/coveralls-maven-plugin to track code coverage over time

  6. Look at the configuration files:

    codecov.yml is read by javaco.io ???



    .travis.yml for using the Travis on-line service ???

  7. Run the repo’s installation script implementing the pom.xml file specifying Java stuff to be downloaded:

    mvn install
  8. Run manually on a Mac:

    mvn test -Dsurefire.suiteXmlFiles=mac-only.xml

    This opens up several browser programs. In each, go to the same URL, checks if the correct title in HTML was received. Browser windows are closed after each test.

    The browsers are Firefox, Chrome, PhantomJS. Not Safari yet.

    travis server > browsers > clean test mac-only > codecov parallel with sonar > reports to codecov history

  9. Under Results should be no Failures or Errors:

    Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

    Git knows whether the test passed by looking at environment variable. If it is zero, Git continues. Any other number, Git stops.

  10. Scroll back up to see the run times, like this:

    Total time: 19.101 s

    Verify hook execution

    No error message is issued if there is an error.

  11. cd into your repo’s .git/hooks folder and execute the files:


    The most common problem reported is not having the correct permissions set by

    chmod +x git-commit

pre-rebase test

  1. Use a text editor to create in the hooks folder a “pre-rebase” containing this text described in YouTube video Life’s better with Git hooks - Grumpy Gits [17:58] Nov 16, 2015 by Deepank Vora.

    echo "Custom rebasing message."
    exit 1

    (Unlike Windows, Linux defines file handling in the first line inside the file).

    PROTIP: Non-zero finish aborts the commit.

  2. Enable the new script:

    chmod +x pre-rebase

    This would avoid messages such as:

    -bash: ./pre-rebase: No such file or directory
  3. Run the new script to make sure it works:

  4. Open another Terminal shell window to the working directory of the repo to run the git rebase master command.

    You should see the custom message.

    QUESTION: If instead you see:

    Current branch master is up to date.

    View pre-commit.sample

  5. Use a text editor Set to always open .sample files with a text editor.

    #!/bin/sh at the top of the file means that it’s a Bash shell script.

    (Author Junio C Hamano is the primary developer of Git, now works at Google.)

closes or fixes

  1. The following script is save as .git/hooks/commit-msg (with no file extension):

    URL=`git config --get remote.origin.url`
    PROJECT=`basename ${URL} .git | cut -d':' -f2`
    for issue_id in `grep -o -e "\(closes\|fixes\) #[0-9]\+" $1 | cut
    -d'#' -f2`; do
        curl -X PUT -d "closed=1" \

    If this script sees a commit message text containing “closes #” or “fixes #”, the hook closes the issue identified by the number after the # symbol.

  2. Make the file executable to enable this functionality.

    chmod +x *


You can connect to the GitLab API using your API key to perform actions inside GitLab when performing, for example, a commit. This you can do from the client side, but of course, you can also use the server-side hooks, such as post-receive to run programs and scripts after they have reached the remote. An example is at:


Scripts by language

Git will run any script that can run on the command line:

  • Bash shell is the default

  • Ruby
  • Python
  • Groovy
  • PowerShell

PowerShell script

To have Git run a PowerShell script on pre-commit, try to create a shell script

# pre-commit (no file extension)
c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe \
-ExecutionPolicy RemoteSigned -Command .\.git\hooks\pre-commit.ps1

To test, put this pre-commit.ps1 script in the folder:





023 Introduction to Git Hooks by Dan Gitschooldude

gated-commit with git pre-commit [12:41] by fullstack

Git hooks man page

Andrew Burgess for Tuts [7:28] June 28, 2012 describes run of mocha test processed by a Bash script.

https://github.com/typicode/husky Git hooks made easy

More on DevOps

This is one of a series on DevOps:

  1. DevOps_2.0
  2. ci-cd (Continuous Integration and Continuous Delivery)
  3. User Stories for DevOps

  4. Git and GitHub vs File Archival
  5. Git Commands and Statuses
  6. Git Commit, Tag, Push
  7. Git Utilities
  8. Data Security GitHub
  9. GitHub API
  10. TFS vs. GitHub

  11. Choices for DevOps Technologies
  12. Java DevOps Workflow
  13. AWS DevOps (CodeCommit, CodePipeline, CodeDeploy)
  14. AWS server deployment options

  15. Digital Ocean
  16. Cloud regions
  17. AWS Virtual Private Cloud
  18. Azure Cloud Onramp
  19. Azure Cloud
  20. Azure Cloud Powershell

  21. Packer automation to build Vagrant images
  22. Terraform multi-cloud provisioning automation

  23. Powershell Ecosystem
  24. Powershell on MacOS
  25. Powershell Desired System Configuration

  26. Jenkins Server Setup
  27. Jenkins Plug-ins
  28. Jenkins Freestyle jobs
  29. Jenkins2 Pipeline jobs using Groovy code in Jenkinsfile

  30. Dockerize apps
  31. Docker Setup
  32. Docker Build

  33. Maven on MacOSX

  34. Ansible

  35. MySQL Setup

  36. SonarQube static code scan

  37. API Management Microsoft
  38. API Management Amazon

  39. Scenarios for load