4

I am trying to set up a pre-commit hook to test my project before any commit goes through, but I can't find how to make sure that only HEAD (with patches from the current commit) are tested and not the current working_tree (which in most cases is dirty for me).

Solutions found:

Found this link and ended up doing the following.

http://newartisans.com/2009/02/building-a-better-pre-commit-hook-for-git/

# Checkout a copy of the current index into MIRROR
git checkout-index --prefix=$TMPDIR/ -af

# Remove files from MIRROR which are no longer present in the index
git diff-index --cached --name-only --diff-filter=D -z HEAD | \
   (cd $TMPDIR && xargs -0 rm -f --)
poolie
  • 9,289
  • 1
  • 47
  • 74
Sedrik
  • 2,161
  • 17
  • 17
  • What do you mean by "test my repo"? – CB Bailey Sep 21 '11 at 07:06
  • So long as your unit tests are "git aware" and can access `HEAD` versions and not your working tree I can't see an issue. – CB Bailey Sep 21 '11 at 07:20
  • My tests are not "git aware" and just accessing HEAD wont give me my staging areas as well as far as I know. Anyway I found my answer (see accepted solution) – Sedrik Sep 21 '11 at 07:28
  • If your tests aren't git aware then you'll need to either get rid of (perhaps temporarily, e.g. via `stage`) your uncommitted changes or checkout a clean working tree, perhaps via `reset` and `checkout-index`. "Staging areas" may included patches that _aren't_ from the current commit, so you want `HEAD`, not your index/cache/staging area. Fundamentally, if you can't access the git model directly you need a file system area that looks like your `HEAD`. I don't see a way around this. – CB Bailey Sep 21 '11 at 07:33
  • I found a workaround and has update my question with it. Thanks for the help. – Sedrik Sep 21 '11 at 07:50

1 Answers1

1

Going to depend on what you are actually verifying and testing. So if you are trying to see if some content is not being in the files checked in you have to do git diff --cached and not git diffso that you will get the appropriate changes. Similarly, you will have to see what commands you are using and so on.

For the unit test thing, I can suggest something like this ( there will be other ways too):

Write a post-commit ( not a pre-commit) hook like so:

#!/bin/sh
git stash
#run unit tests
#if tests fail
git stash pop --index
git reset --soft HEAD~1 
exit 0   # if tests pass

Alternative using pre-commit would be to checkout the index into a separate directory, run the tests from there. Have a look at git checkout-index. I haven't used it in this way, so cannot comment further on it.

manojlds
  • 290,304
  • 63
  • 469
  • 417
  • 1
    I want to make sure that when I run my unit test it will run on HEAD and my staged commits. – Sedrik Sep 21 '11 at 07:18
  • @Sedrik - Updated my answer with a possible solution. – manojlds Sep 21 '11 at 07:30
  • `git stash` removes the staged files as well so it wont work. Found a reasonable solution and edited my question. – Sedrik Sep 21 '11 at 07:32
  • @Sedrik - I think you did not notice that I am talking of `post-commit` hook and not pre-commit in this case. So your changes in index are comitted and git stash will work as expected – manojlds Sep 21 '11 at 07:35
  • A true, failed to not that. Then it will of course work, did not think of doing it that way. Thanks for your help :) – Sedrik Sep 21 '11 at 07:49