Skip to content

Instantly share code, notes, and snippets.

@lyrixx
Created June 26, 2013 13:37
Show Gist options
  • Save lyrixx/5867424 to your computer and use it in GitHub Desktop.
Save lyrixx/5867424 to your computer and use it in GitHub Desktop.
Git post checkout
#!/bin/bash
# Put this file at: .git/hooks/post-checkout
# and make it executable
# You can install it system wide too, see http://stackoverflow.com/a/2293578/685587
PREV_COMMIT=$1
POST_COMMIT=$2
NOCOLOR='\e[0m'
REDCOLOR='\e[37;41m'
if [[ -f composer.lock ]]; then
DIFF=`git diff --shortstat $PREV_COMMIT..$POST_COMMIT composer.lock`
if [[ $DIFF != "" ]]; then
echo -e "$REDCOLOR composer.lock has changed. You must run composer install$NOCOLOR"
fi
fi
@jubianchi
Copy link

I use something similar for nodejs/PHP projects.

@hardchor
Copy link

Brilliant, thanks for that

@lyrixx
Copy link
Author

lyrixx commented Jun 26, 2013

@jubianchi I'm wondering why I did not do that this before

@lyrixx
Copy link
Author

lyrixx commented Jun 26, 2013

@hardchor Thanks.

@jubianchi
Copy link

@lyrixx I asked myself the same question :)
I used composer for monthes and only had the idea when moving to nodejs :/

Now I'm wondering if it would be possible to automatically run the composer/npm commands... It would be really great if everything was handled without having to do anything ;)

@jubianchi
Copy link

This hook completly automates the process : when a change is detected on composer.lock or package.json the commands are automatically launched (composer install / npm install) unless you are in the middle of a rebase or a merge: in this case, you'll only get a warning and you'll have to manually execute the commands when you are ready.

#!/bin/bash

# Put this file at: .git/hooks/post-checkout
# and make it executable
# You can install it system wide too, see http://stackoverflow.com/a/2293578/685587

PREV_COMMIT=$1
POST_COMMIT=$2

GIT_DIR=$(git rev-parse --git-dir)
GIT_DIR_MERGE="$GIT_DIR"/rebase-merge
GIT_DIR_APPLY="$GIT_DIR"/rebase-apply

GIT_MERGE_REBASE=false
[[ (-d "$GIT_DIR_MERGE" && -f "$GIT_DIR_MERGE/interactive") || -d "$GIT_DIR_APPLY" ]] && GIT_MERGE_REBASE=true

NOCOLOR='\e[0m'
REDCOLOR='\e[37;41m'

function composer.lock {
    echo -e "$REDCOLOR composer.lock has changed: running composer install $NOCOLOR"

    COMPOSER=
    if [ -f composer.phar ]; then
        COMPOSER="php composer.phar"
    fi

    which composer > /dev/null 2>&1
    if [ $? ]; then
        COMPOSER="composer"
    fi

    if [[ $GIT_MERGE_REBASE = false && -n "$COMPOSER" ]]; then
        $COMPOSER install
    fi
}

function package.json {
    echo -e "$REDCOLOR package.json has changed: running npm install $NOCOLOR"

    which npm > /dev/null 2>&1
    if [[ $GIT_MERGE_REBASE = false && $? ]]; then
        npm install
    fi
}

FUNCS=$(declare -F -p | cut -d " " -f 3)
for FUNC in $FUNCS
do
    DIFF=$(git diff --shortstat $PREV_COMMIT..$POST_COMMIT $FUNC 2>/dev/null)
    if [[ $DIFF != "" ]]; then
        $FUNC
    fi
done

@marekkalnik
Copy link

Thanks ! 👍

@pietervogelaar
Copy link

Wow, awesome!!

@skyzyx
Copy link

skyzyx commented Jun 29, 2013

Using the version by @jubianchi on OS X I get

.git/hooks/post-checkout: line 36: `composer.lock': not a valid identifier

@fzaninotto
Copy link

Other solution: commit your dependencies.

@jubianchi
Copy link

@fzaninotto: I usually apply the following rule: I only commit the code that I am maintaining. Committing dependencies sometimes lead to a messy or too big repository, depending on what is inside dependencies.

@skyzyx here is a potential fix:

#!/bin/bash

# Put this file at: .git/hooks/post-checkout
# and make it executable
# You can install it system wide too, see http://stackoverflow.com/a/2293578/685587

PREV_COMMIT=$1
POST_COMMIT=$2

GIT_DIR=$(git rev-parse --git-dir)
GIT_DIR_MERGE="$GIT_DIR"/rebase-merge
GIT_DIR_APPLY="$GIT_DIR"/rebase-apply

GIT_MERGE_REBASE=false
[[ (-d "$GIT_DIR_MERGE" && -f "$GIT_DIR_MERGE/interactive") || -d "$GIT_DIR_APPLY" ]] && GIT_MERGE_REBASE=true

NOCOLOR='\e[0m'
REDCOLOR='\e[37;41m'

function composerlock {
    echo -e "$REDCOLOR composer.lock has changed: running composer install $NOCOLOR"

    COMPOSER=
    if [ -f composer.phar ]; then
        COMPOSER="php composer.phar"
    fi

    which composer > /dev/null 2>&1
    if [ $? ]; then
        COMPOSER="composer"
    fi

    if [[ $GIT_MERGE_REBASE = false && -n "$COMPOSER" ]]; then
        $COMPOSER install
    fi
}

function packagejson {
    echo -e "$REDCOLOR package.json has changed: running npm install $NOCOLOR"

    which npm > /dev/null 2>&1
    if [[ $GIT_MERGE_REBASE = false && $? ]]; then
        npm install
    fi
}

FUNCS=$(declare -F -p | cut -d " " -f 3)
for FUNC in $FUNCS
do
    DIFF=$(git diff --shortstat $PREV_COMMIT..$POST_COMMIT $FUNC 2>/dev/null)
    if [[ $DIFF != "" ]]; then
        $FUNC
    fi
done

@cordoval
Copy link

@TxHawks
Copy link

TxHawks commented Aug 25, 2016

@jubianchi -
I'm aware this is old, but there is a bug in your script:
$GIT_MERGE_REBASE will always be false, as the hook is run before the rebase_apply dir is created. At least in git 2.9

@andkirby
Copy link

andkirby commented Jul 13, 2017

Quick download of this file from CLI:

curl -Ls https://gist.githubusercontent.com/lyrixx/5867424/raw/0af090ab37d07a4d814c1ee2a267fad90767565d/post-checkout \
  > "$(git rev-parse --git-dir)/hooks/post-checkout"

@andkirby
Copy link

andkirby commented Jul 13, 2017

Guys, is there any chance to run it on git pull/merge? In a nutshell, on any update.
Hook files as post-update, post-receive don't work.

I made this script for testing and it didn't show any red message.

git checkout 1.1.0
git branch -d master
git checkout 1.1.0 -b master
git branch --set-upstream-to=origin/master master
git pull

@robrecord
Copy link

@andkirby don't forget to chmod +x

curl -Ls https://gist.githubusercontent.com/lyrixx/5867424/raw/0af090ab37d07a4d814c1ee2a267fad90767565d/post-checkout \
  > "$(git rev-parse --git-dir)/hooks/post-checkout" && chmod +x "$(git rev-parse --git-dir)/hooks/post-checkout"

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