Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
git hook to run a command after `git pull` if a specified file was changed.In this example it's used to run `npm install` if package.json changed and `bower install` if `bower.json` changed.Run `chmod +x post-merge` to make it executable then put it into `.git/hooks/`.
#!/usr/bin/env bash
# MIT © Sindre Sorhus - sindresorhus.com
# git hook to run a command after `git pull` if a specified file was changed
# Run `chmod +x post-merge` to make it executable then put it into `.git/hooks/`.
changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"
check_run() {
echo "$changed_files" | grep --quiet "$1" && eval "$2"
}
# Example usage
# In this example it's used to run `npm install` if package.json changed
check_run package.json "npm install"
@GianlucaGuarini

This comment has been minimized.

Copy link

GianlucaGuarini commented Dec 17, 2013

It works like a charm but I had to fork it https://gist.github.com/GianlucaGuarini/8001627

@therealklanni

This comment has been minimized.

Copy link

therealklanni commented Jun 20, 2014

curl -O https://gist.githubusercontent.com/sindresorhus/7996717/raw/4ec63bc6f8c0f1e227faeb78eddc01a788ef0595/post-merge && chmod +x post-merge && mv post-merge .git/hooks/
@MoOx

This comment has been minimized.

Copy link

MoOx commented Jun 24, 2014

How can we share a git hook with the team ?

@MoOx

This comment has been minimized.

@yangg

This comment has been minimized.

Copy link

yangg commented Sep 4, 2014

Failed to run in windows, fix it by add a ! sign , #!/usr/bin/env bash

@robertcasanova

This comment has been minimized.

Copy link

robertcasanova commented Apr 27, 2015

This hook doesn't work if you run pull with --rebase option. Do you know how to fix it? Thx!

@danielcgold

This comment has been minimized.

Copy link

danielcgold commented Apr 29, 2015

I forked this to work with changes to .scss and .sass file changes. https://gist.github.com/danielcgold/6de270807fc01c793c9a

@mariusGundersen

This comment has been minimized.

Copy link

mariusGundersen commented May 13, 2015

It seems like HEAD@{1} should be used instead of ORIG_HEAD. Forked here: https://gist.github.com/mariusGundersen/8a4383f74a46ababc1de

@aaronroberson

This comment has been minimized.

Copy link

aaronroberson commented Jun 3, 2015

@robertcasanova take a look at .git/hooks/pre-rebase.sample and see if you can deduct how to do a post-rebase hook.

@gtramontina

This comment has been minimized.

Copy link

gtramontina commented Jun 18, 2015

@MoOx (and anyone interested): If you're using npm : https://github.com/gtramontina/ghooks

@DimeZilla

This comment has been minimized.

Copy link

DimeZilla commented Aug 13, 2015

@sindresorhus this is awesome! thank you!

@Satys

This comment has been minimized.

Copy link

Satys commented Aug 18, 2015

Does post-merge run when there are conflicts during pull?

@slattery

This comment has been minimized.

Copy link

slattery commented Aug 19, 2015

@Satys.

No, it won't run. "This hook cannot affect the outcome of git merge and is not executed, if the merge failed due to conflicts."

@PunKeel

This comment has been minimized.

Copy link

PunKeel commented Sep 4, 2015

❤️

@icamys

This comment has been minimized.

Copy link

icamys commented Apr 14, 2016

I would add these checks too:

# Updating git submodules
check_run .gitmodules "git submodule init && git submodule update"

# Installing composer dependencies
check_run composer.json "composer install"

# For those who use gulp
check_run web/assets "gulp --production"
@wzpan

This comment has been minimized.

Copy link

wzpan commented Apr 18, 2016

@robertcasanova

This hook doesn't work if you run pull with --rebase option. Do you know how to fix it? Thx!

+1 , same problem. Have you found out the solution?

@aaronroberson

take a look at .git/hooks/pre-rebase.sample and see if you can deduct how to do a post-rebase hook.

I've tried to write a post-rebase hook but it didn't work ...

@tkalfigo

This comment has been minimized.

Copy link

tkalfigo commented May 20, 2016

First line missing a !; should be #!/usr/bin/env bash

@belveryin

This comment has been minimized.

Copy link

belveryin commented May 20, 2016

post-rewrite works for me. As side effect it is also executed on amend.

http://stackoverflow.com/questions/21307744/git-post-rebase-hook

@jplagostena

This comment has been minimized.

Copy link

jplagostena commented Jun 14, 2016

Awesome! Thanks! It works like a charm.

@marcvangend

This comment has been minimized.

Copy link

marcvangend commented Jul 18, 2016

For package managers that use a lock file, eg. Composer, it would make sense to check if the lock file changed rather than the requirements file, right? In other words:

# Installing composer dependencies
check_run composer.lock "composer install"
@betorobson

This comment has been minimized.

Copy link

betorobson commented Feb 20, 2017

Thank you so much, it works like a charm although, I did a few changes on my fork.
https://gist.github.com/betorobson/23e5914b51e844bac5eaa6032d6f3f88

@jth41

This comment has been minimized.

Copy link

jth41 commented May 9, 2017

On my machine it is running npm install whether package.json is changed or not.

The way I am reproducing is by creating a new branch at the current commit and then checking it out. Therefore the files should be identical between the two branches.

Anyone have any ideas?

cross-posted with stackoverflow: http://stackoverflow.com/questions/43876375/optional-githook-behaving-as-non-optional

@rlafuente

This comment has been minimized.

Copy link

rlafuente commented May 23, 2017

For cases where you are pushing to a bare repo and want to use this on a post-receive hook, instead of the line

changed_files="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"

one should use

changed_files="$(git diff --name-only HEAD^ HEAD)"

Thank you for an extremely useful snippet!

@anoobbava

This comment has been minimized.

Copy link

anoobbava commented Nov 17, 2017

This only deals with changed files right. Suppose I want to check any new files are generated when taking pull, how this solution works?

@oriy

This comment has been minimized.

Copy link

oriy commented Aug 10, 2018

thanks for the wonderful solution
extended the script - added the option for conditionally execute the command according to git configuration
https://gist.github.com/oriy/e8b58a6a471d371129b1d0b430510375

@samuelj90

This comment has been minimized.

Copy link

samuelj90 commented Nov 22, 2018

@sindresorhus Thanks for the wonderful solution.
I would like to clarify that Is it possible to check and run npm install only if the change is in npm dependency ?
I think that will save some more time.

@drAlberT

This comment has been minimized.

Copy link

drAlberT commented Feb 11, 2019

@robertcasanova

This hook doesn't work if you run pull with --rebase option. Do you know how to fix it? Thx!

+1 , same problem. Have you found out the solution?

@aaronroberson

take a look at .git/hooks/pre-rebase.sample and see if you can deduct how to do a post-rebase hook.

I've tried to write a post-rebase hook but it didn't work ...

post-rebase is not a valid git-hook

You have to implement a post-rewrite hook and check the first argument to be "rebase" (could be "amend" too as @belveryin already tasted).
See https://git-scm.com/docs/githooks#_post_rewrite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.