1

Situation

I have a copy of a git repository on my local system, as well as a second one on a remote server (both non-bare). Due to environmental constraints, I'm forced to use Git 1.8 on both.

On the server, I have [receive] denyCurrentBranch = ignore in .git/config , and git reset --hard in .git/hooks/post-receive . This allows me to emulate the denyCurrentBranch = updateInstead behavior.

I'm trying to add a pre-receive hook that will fail when I don't have a clean head.

Attempt

On the server, if I run git status I have the following:

[server test_app]$ git status
# On branch master
nothing to commit, working directory clean

I had planned to add git status in the hook, something like this (pseudo-bash):

((git status | grep "On branch master" | wc -l) == 1) && ((git status | grep "nothing to commit, working directory clean" | wc -l) == 1) && (exit 0)
exit 1

To test if this was possible, I tried the following in my hook

git status
exit 1

Results

When I try to push, I get the following:

Pushing to ssh://.../test_app
remote: # On branch master[K
remote: # Changes not staged for commit:[K
remote: #   (use "git add/rm <file>..." to update what will be committed)[K
remote: #   (use "git checkout -- <file>..." to discard changes in working directory)[K
remote: #[K
remote: #   deleted:    bin/README[K
remote: #[K
remote: # Untracked files:[K
remote: #   (use "git add <file>..." to include in what will be committed)[K
remote: #[K
remote: #   COMMIT_EDITMSG[K
remote: #   HEAD[K
remote: #   ORIG_HEAD[K
remote: #   config[K
remote: #   description[K
remote: #   hooks/[K
remote: #   index[K
remote: #   info/[K
remote: #   logs/[K
remote: #   objects/[K
remote: #   refs/[K
remote: no changes added to commit (use "git add" and/or "git commit -a")[K
remote: I will fail[K
To ssh://.../test_app
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'ssh://.../test_app'

Conclusion

I assume this means I'm misunderstanding what state git is in at the pre-receive hook. What should I have in my pre-receive (or some other) hook to prevent an update when the working directory isn't clean?

Zeophlite
  • 1,607
  • 3
  • 19
  • 36

1 Answers1

0

Thanks to http://longair.net/blog/2011/04/09/missing-git-hooks-documentation/ and reset hard on git push , I've found out that pre-receive sets the working directory and the GIT_DIR environmental variable to the .git/ folder.

Thus the following is sufficient

git --git-dir=. --work-tree=$PWD/.. status

The entire hook for anyone interested:

#!/bin/bash

data=`git --git-dir=. --work-tree=$PWD/.. status`
val=`echo $data | grep "working directory clean" | wc -l`

if [ $val -eq 1 ]
then
  echo "All good"
  exit 0
else
  echo "I will fail"
  echo $data
  exit 1
fi
Community
  • 1
  • 1
Zeophlite
  • 1,607
  • 3
  • 19
  • 36