Skip to content

Instantly share code, notes, and snippets.

@GianlucaGuarini
Forked from sindresorhus/post-merge
Last active August 22, 2023 20:54
Show Gist options
  • Save GianlucaGuarini/8001627 to your computer and use it in GitHub Desktop.
Save GianlucaGuarini/8001627 to your computer and use it in GitHub Desktop.
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
Copy link

This looks slick. How has it been working out?

@GianlucaGuarini
Copy link
Author

Modern web development needs ;)

@max-mykhailenko
Copy link

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
Copy link
Author

@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
Copy link

What about a solution for checkout?

@GianlucaGuarini
Copy link
Author

@naXa777
Copy link

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
Copy link

samuelj90 commented Nov 22, 2018

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

@digeomel
Copy link

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
Copy link
Author

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
Copy link

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
Copy link
Author

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
Copy link

digeomel commented Feb 4, 2021

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

@airtonix
Copy link

airtonix commented Jul 9, 2021

  • The PR gets merged into develop and anyone in your team knows that pulling from develop means triggering npm i

how would they know?

it's not feasiable to have everyone in your 250+ team look at that PR before it gets merged.

@annapoulakos
Copy link

  • The PR gets merged into develop and anyone in your team knows that pulling from develop means triggering npm i

how would they know?

it's not feasiable to have everyone in your 250+ team look at that PR before it gets merged.

This is why you would use githooks. If there is something you should do on every pull or every commit, then you definitely should be using githooks to automate that.

One thing that I can't stress enough when I am working with large organizations is that people are really, really good at one thing: making mistakes. Good automation practices help resolve this, and while you cannot automate everything, you certainly can automate almost everything.

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