Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Git hook that gets triggered after any 'git pull' whenever one of the files specified has changed. Useful to update any web application dependency using bower npm or composer

How to create a global git commit hook by Matt Venables

1 Enable git templates (This tells git to copy everything in ~/.git-templates to your per-project .git/ directory when you run git init):

git config --global init.templatedir '~/.git-templates'

2 Create a directory to hold the global hooks:

mkdir -p ~/.git-templates/hooks

3 Write your hooks in ~/.git-templates/hooks. For example, here's a post-commit hook (located in ~/.git-templates/hooks/post-commit):


#!/bin/sh

# Copy last commit hash to clipboard on commit
git log -1 --format=format:%h | pbcopy


# Add other post-commit hooks 

4 Make sure the hook is executable.

chmod a+x ~/.git-templates/hooks/post-commit

5 Re-initialize git in each existing repo you'd like to use this in:

git init

NOTE if you already have a hook defined in your local git repo, this will not overwrite it.

#/usr/bin/env bash
# MIT © Sindre Sorhus - sindresorhus.com
# forked by Gianluca Guarini
changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
check_run() {
echo "$changed_files" | grep -E --quiet "$1" && eval "$2"
}
# `npm install` and `npm prune` if the `package.json` file gets changed
# to update all the nodejs ( grunt ) dependencies deleting the unused packages (not listed into the `package.json` file)
check_run package.json "npm install && npm prune"
# `bower install` and `bower prune` if the `bower.json` file gets changed
# to install all the frontend dependencies removing the unused packages ( not listed into the `bower.json` file )
check_run bower.json "bower install && bower prune"
# `composer install` if the `composer.json` file gets changed
# to update all the php dependencies
check_run composer "sudo composer install"
# for the sass files we need a bit more
if [ -f "config.rb" ]
then
# `compass compile` to compile all the scss files when they get changed
check_run ".scss|.sass" "compass compile"
# check whether there is a gruntfile in the root of the project
elif [[ -n $(find . -maxdepth 1 -iname "gruntfile.js" -o -iname "gruntfile.coffee") ]]
then
# try to compile just using grunt sass
check_run ".scss|.sass" "grunt sass"
# check whether there is a gulpfile in the root of the project
elif [[ -n $(find . -maxdepth 1 -iname "gulpfile.js" -iname "gulpfile.coffee") ]]
then
# try to compile just using grunt sass
check_run ".scss|.sass" "gulp sass"
fi
@ericrowan

This comment has been minimized.

Copy link

@ericrowan ericrowan commented Aug 19, 2014

This looks slick. How has it been working out?

@GianlucaGuarini

This comment has been minimized.

Copy link
Owner Author

@GianlucaGuarini GianlucaGuarini commented Sep 9, 2014

Modern web development needs ;)

@max-mykhailenko

This comment has been minimized.

Copy link

@max-mykhailenko max-mykhailenko commented Jan 31, 2015

Where I can read about this conditions elif [[ -n $(find . -maxdepth 1 -iname "gruntfile.js" -o -iname "gruntfile.coffee") ]]. Can you comment different between them?

@GianlucaGuarini

This comment has been minimized.

Copy link
Owner Author

@GianlucaGuarini GianlucaGuarini commented Feb 3, 2015

@max-mykhailenko here I just try to find the gruntfile.js or gruntfile.coffee in the root of the project to trigger grunt sass that is normally the task I use to compile the scss files

@vitalybe

This comment has been minimized.

Copy link

@vitalybe vitalybe commented Mar 24, 2015

What about a solution for checkout?

@GianlucaGuarini

This comment has been minimized.

Copy link
Owner Author

@GianlucaGuarini GianlucaGuarini commented Aug 18, 2015

@naXa777

This comment has been minimized.

Copy link

@naXa777 naXa777 commented Jan 15, 2016

@vitalybe (and others) Note that for post-checkout hook you should compare revisions provided in arguments to the hook:
changed_files="$(git diff-tree -r --name-only --no-commit-id $1 $2)"

@samuelj90

This comment has been minimized.

Copy link

@samuelj90 samuelj90 commented Nov 22, 2018

Is it possible to limit npm install only if there is any change in npm dependency

@digeomel

This comment has been minimized.

Copy link

@digeomel digeomel commented Feb 3, 2021

Alas, it doesn't seem to work with git pull.rebase = true. I have both a post-checkout and a post-merge hook and neither works. Tried with a post-rewrite hook, and no luck again. Any suggestions? git version 2.28.0.windows.1

@GianlucaGuarini

This comment has been minimized.

Copy link
Owner Author

@GianlucaGuarini GianlucaGuarini commented Feb 4, 2021

I wrote this gist many years ago. My recommendation in 2021 is to handle these scripts manually avoiding the git hooks. Today I prefer having more control over what's happening in my projects instead of magically trigger scripts via git.

@digeomel

This comment has been minimized.

Copy link

@digeomel digeomel commented Feb 4, 2021

@GianlucaGuarini thank you for your answer. Care to elaborate a little more? What would you use today? Watchers?

My case is that we work with other developers and I want to know when somebody has updated the package.json file (so I have to run npm install) or somebody has updated the GraphQL schema (in which case I need to run some other tools).

@GianlucaGuarini

This comment has been minimized.

Copy link
Owner Author

@GianlucaGuarini GianlucaGuarini commented Feb 4, 2021

The Key to solve these issues is communication, you can not automate everything.
A smart use of git branches and releases can help your team tracking the stuff to do to work on the project.
For example:

  • A new Frontend dependency gets added and package.json + package-lock.json got updated
  • The new dependency will be added in feature/add-markdown-reader
  • The Github PR gets opened and reviewed by the frontend team
  • The PR gets merged into develop and anyone in your team knows that pulling from develop means triggering npm i
@digeomel

This comment has been minimized.

Copy link

@digeomel digeomel commented Feb 4, 2021

That wouldn't work for us, we're not using Github or this particular workflow, but thank you 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment