Git post-receive hook not working

We’re using git with a central repo (using Gitosis). I’ve created a post-receive hook to generate an email to the dev mailing list whenever changes are pushed to the central repo, and to generate documentation from the documentation folder in the git repo.

Therefore, in ~git/ I’ve got a directory, we’ll call it ‘a’ that contains a clone of the git repo. The post-receive hook looks like:

  • How can I run the makefile on every git branch
  • git diff during pre-commit hook results in Not a git repository
  • In Git Bash on Windows 7, Colors display as code when running Cucumber or rspec
  • Git Bash only working when Trend Micro is disabled
  • PS1 line with git current branch and colors
  • Git 2.5.1's bash console doesn't open python interpreter
  • #!/bin/bash
    cd ~git/repositories/a.git
    . ~git/post-receive-email &> /dev/null
    ( cd ~git/a && git pull &> ~git/pull_log.log && php ~git/a/scripts/generate_markdown_documentation.php &> ~git/doc_log.log )
    

    The email script is working, but the documentation generation is not. The content of pull_log.log is:

    fatal: Not a git repository: '.'
    

    Which makes me think that it’s not changing to the correct directory in line 5 of the above script. Am I wrong? How can I get this to work?

    Edit: I’ve updated the post-receive hook as suggested in the responses. The script is now:

    #!/bin/bash
    function die {
      echo "$*" >&2; exit 1
    }
    
    function checkgit {
      [ -d "$1/.git" ] || die "$1 could not possibly be a git repo; $1/.git is not a dir"
    }
    
    
    cd ~git/repositories/a.git
    . ~git/post-receive-email &> /dev/null
    ( set -x
    checkgit ~git/a
    cd ~git/a
    checkgit .
    pwd
    git pull
    php ~git/a/scripts/generate_markdown_documentation.php )
    

    And I get the following output from git push:

    + checkgit /var/git/a
    + '[' -d /var/git/a/.git ']'
    + cd /var/git/a
    + checkgit .
    + '[' -d ./.git ']'
    + pwd
    /var/git/a
    + git pull
    fatal: Not a git repository: '.'
    + php /var/git/a/scripts/generate_markdown_documentation.php
    

    Any more help?

    Oh, and if I run the script myself, it works (I run it by saying hooks/post-receive)

    Discovered the problem, thanks to serverfault — basically, environment variables GIT_DIR and GIT_WORK_TREE are set when the hook runs, and these affect git pull adversely. Unsetting the variables fixes the problem.

  • Xcode project syncing over cloud service
  • Is “Merged in” a commit message created by bitbucket, or git?
  • Merge a git branch with master a second time because the first changes were removed due to conflict
  • Fix Git “object not found” for good
  • Storing submodules for micro services, but still using forks
  • Git merge: take everything from “theirs” branch
  • 3 Solutions collect form web for “Git post-receive hook not working”

    You need more diagnostics, e.g.,

    function die {
      echo "$*" >&2; exit 1
    }
    
    function checkgit {
      [ -d "$1/.git" ] || die "$1 could not possibly be a git repo; $1/.git is not a dir"
    }
    

    At this point, in the subshell right after the parenthesis, you can try stuff like

    set -x # show exactly what's executed (writes to stderr)
    checkgit ~git/a
    cd ~git/a && checkgit . && git pull ...
    

    You might also consider redirecting the whole stderr of the subshell, e.g.,

    ( ... ) 2>/tmp/mydiagnosis$$.log
    

    (This is a temporary measure and is OK only if there’s no confidential info in the logs.)


    OK Silas, your additional info rules out a lot of awkward possibilities. I’m nearing the end of my git fu, but here are some more things to try:

    1. Go into ~git/a and see if you can make it git pull by hand. This should fail.
    2. Got into ~git/a and run git status. This should also fail. If it doesn’t, then git is giving you a very bad error message.

    If both steps fail, ~git/a is not the clone you thought it was. Rename it, make a new clone, and see if you can get the problem to persist.

    If the first step succeeds by hand, then something strange is going on and I’m baffled.

    If the first step fails but the second succeeds, you may have a problem with branches:

    • Perhaps repo ~git/a is set to the wrong branch, and your repo needs a branch it doesn’t have. Try git branch -a and see if you see something unexpected.

    • Perhaps you have the branch, but it’s not properly associated with a remote repository. At this point you have to dive into ~git/a/.git/config, and I don’t really know how to explain what you should expect to find there. At that point you will need a real git expert; I just play one on TV.

    I recently ran into a similar problem and I think it is related to the environment variables that git sets, specifically the $GIT_DIR variable. If you have that set, all git commands on other repos start to act weirdly. Basically I think that running your git pull inside the hook must be invoked in a neutral shell environment that does not have those odd variables and leads to git confusion, though I haven’t figured out how to do that just yet.

    unset GIT_DIR is a solution which works for the fatal error you are seeing.

    This applies to all scripts in hooks (post-update is another common one), which uses the git command inside it. git command uses the GIT_DIR from env instead of pwd.

    See https://stackoverflow.com/a/4100577 for further explanation.

    Git Baby is a git and github fan, let's start git clone.