This is what I use with django+south to prevent forgetting to commit migrations:<p><pre><code> MIGRATIONS_DIRECTORIES="$(find -type d -iname migrations)"
UNTRACKED_MIGRATIONS="$(git ls-files --exclude-standard --others -- $MIGRATIONS_DIRECTORIES | egrep '(.*)[.]py$')"
if test -z "$UNTRACKED_MIGRATIONS"; then
# If there are no untracked .py files in the migrations directory, do nothing, allow commit.
true;
else
# If there are untracked files in the migrations directory print a warning message.
echo "Warning -- Untracked files in the migrations directory"
echo 'The commit may be forced with "git commit --no-verify"'
echo
echo "$UNTRACKED_MIGRATIONS"
exit 1
fi</code></pre>
I can't get behind pre-commit hooks.<p>1) Sometimes (usually the worst times) you just need to check something in, maybe it doesn't pass pep8 but when service is down nobody gives a shit.<p>2) Instead of promoting thinking and caution it promotes attitude of "hey check it in and see if it sticks".<p>Post commit hooks that report broken tests, poor code, etc preferable to whole team are far superior. After first couple of times being shamed people will actually look over their code, run tests, run pep8, etc to verify the commit isn't bogus.
This is my pre-commit hook for Django projects: <a href="https://gist.github.com/858223" rel="nofollow">https://gist.github.com/858223</a><p>It just runs pyflakes and does some sanity checking. Best of all, it doesn't go around stashing files or otherwise messing with your working directory or repository. It just uses some git plumbing commands to copy the current index (what you're about to commit) to a temporary directory.<p>I can't remember where I copied it from but it works perfectly, only copying whatever I'm about to commit:<p><pre><code> git diff --cached --name-only --diff-filter=ACMR | xargs git checkout-index --prefix=$TMPDIR/ --
</code></pre>
I can't say how many times this saved me from leaving a pdb.set_trace() in a view somewhere...
Personally, I find pre-commit hooks to be a throw-back to older RCSes. For modern systems like Git I would prefer to have a pre-<i>merge</i> hook. That is to say, commit any old crap you want to your local branch but you're not merging with the main development branch until your code is proven to pass the test suite. And only code that is in the mainline dev branch can be merged to main, etc.
Here's my bash pre-commit hook to check for PHP syntax errors and accidentally committed merge conflicts: <a href="https://github.com/dave1010/scripts/blob/master/git-hooks/pre-commit" rel="nofollow">https://github.com/dave1010/scripts/blob/master/git-hooks/pr...</a>
I think it's a bit overkill to say any pre-commit hook that doesn't stash before running is 'wrong'. If nobody thought to stash before checking the files, maybe nobody else has a workflow that would require it. For me, staging and committing happen in immediate succession, so there wouldn't be any edits that aren't staged. If you work in a way that requires it then go right ahead, but what's the deal lately with calling everyone else 'wrong'?
Here is mine:<p><a href="https://github.com/lbolla/dotfiles/blob/master/githooks/pre-commit" rel="nofollow">https://github.com/lbolla/dotfiles/blob/master/githooks/pre-...</a><p>It PEP8-fies and pyflakes .py files and gjslint-ifies .js files.
Other actions can be easily added!