Sometimes when working on a PHP project where there are a lot of branches potentially sitting on incompatible packages, it can be a pain to always remember to manually run composer i or whatever docker alternative or alias one might be using. After forgetting, there are error messages appearing cluttering logs and everyone watching while simultaneously wasting time.

I tried to modify this stack overflow answer to see if this could be comfortably automated via git hooks. Here are the original steps from the answer for the record. Start by chreating the post-checkout git hook with executable flag:

touch .git/hooks/post-checkout
chmod u+x .git/hooks/post-checkout

Paste this contents there:

#!/bin/bash

set -e

printf '\npost-checkout hook\n\n'

prevHEAD=$1
newHEAD=$2
checkoutType=$3

[[ $checkoutType == 1 ]] && checkoutType='branch' ||
                            checkoutType='file' ;

echo 'Checkout type: '$checkoutType
echo '    prev HEAD: '`git name-rev --name-only $prevHEAD`
echo '     new HEAD: '`git name-rev --name-only $newHEAD`

This at least got me on the track. Now let's transform it to actually run composer install when different branch is checked out. Note that we do not really need to check if file is checked out or it is actually a branch, because checking out a file is not that frequent and also running composer is designed to not cause problems:

#!/bin/bash

set -e

prevHEAD=$1
newHEAD=$2

if [ "$newHEAD" != "$prevHEAD" ]; then
    composer i
fi

Now test with git checkout somebranch. Works? Yes. Comfortable? Hell no! The main problem here is that it blocks your terminal till the composer is installing. Let's incorporate some advice from another answer explaining how to run the long-running command in the background:

long-running-command >&- 2>&- &

Alternatively, the same can be done by the following, choose whichever syntax suits you best:

long-running-command >/dev/null 2>&1 &

The above works by redirecting both stderr and stdout into the grinder and adding & at the end, putting the command to the background. Here's the final script:

#!/bin/bash

set -e

prevHEAD=$1
newHEAD=$2

if [ "$newHEAD" != "$prevHEAD" ]; then
    printf "Post-checkout 'composer install' hook active.\n"
    composer i >/dev/null 2>&1 &
fi

Now use git checkout - to easily change changes back-and-forth and observe processes. You should be able to see a brief peak in the CPU usage in the very least after every checkout:

$ git checkout -
Switched to branch 'somebranch'
Post-checkout 'composer install' hook active.
$ git checkout -
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
Post-checkout 'composer install' hook active.

Enjoy!