100

Experimentally it seems that git hooks get run with the current directory set to be the root of the repository. However, I can't see any guarantee about that in the git documentation. Should I rely on the current working directory to locate the git repository, or is there a better way to work out the git repository associated with the hook?

Dickon Reed
  • 3,575
  • 4
  • 23
  • 25
  • 4
    Not sure how much that is related. On a Gentoo stable box with Git 2.7.3(-r1) git hooks are not only executed in `.git` but `git reset --hard` actually creates the working directory structure inside the `.git` directory which, in my opinion is an entirely wrong thing to do! – Pavel Šimerda Oct 29 '16 at 22:00

3 Answers3

113

The current answers appear to be outdated. As of 2.9.0, the docs state the following:

Before Git invokes a hook, it changes its working directory to either the root of the working tree in a non-bare repository, or to the $GIT_DIR in a bare repository.

https://git-scm.com/docs/githooks/2.9.0

Ohad Schneider
  • 36,600
  • 15
  • 168
  • 198
  • 22
    Great answer. A clarification was made in later revisions (2.13.0). **"An exception are hooks triggered during a push (pre-receive, update, post-receive, post-update, push-to-checkout) which are always executed in $GIT_DIR."** – Novice C Sep 28 '17 at 06:28
  • 3
    Source/context for the above quote: https://git-scm.com/docs/githooks#_description – jmcker Nov 27 '18 at 05:51
  • 3
    In plain language: it's the top-level directory of your repository. ("Bare" essentially refers to a repository consisting of only the `.git` directory, and with no files checked out.) – Ben Mares Oct 03 '20 at 19:52
47

It is based on the value set for environment variable GIT_DIR. It is set to the root of the repository when the hook starts running. Many hooks, especially those doing a pull from another repo, unset ( and reset) this environment variable as needed.

manojlds
  • 290,304
  • 63
  • 469
  • 417
  • 6
    Does $GIT_DIR has a trailing slash ? – PuercoPop Apr 10 '12 at 04:34
  • 10
    This is NOT a correct answer. GIT_DIR is NOT always set to the root of the repo. See [this blog](http://longair.net/blog/2011/04/09/missing-git-hooks-documentation/). – Ghopper21 Dec 17 '15 at 21:15
  • 2
    @Ghopper21 That article isn't entirely correct either. It says that for the post-commit hook, the current directory is the top level of the working tree. However, my very simple post-commit script didn't find other scripts at the top level of the working tree. e.g.: `.git/hooks/post-commit: 1: .git/hooks/post-commit: post-commit_push_gitweb.sh: not found` – Vince Feb 26 '16 at 05:48
4

You can use the environment variable $GIT_DIR. $GIT_DIR points at the .git directory.

0xcaff
  • 13,085
  • 5
  • 47
  • 55
holygeek
  • 15,653
  • 1
  • 40
  • 50
  • 1
    How likely is it that `$GIT_DIR/..` will point to the repository root? – David Lord Sep 14 '15 at 04:47
  • It's not foolproof. Don't use ``$GIT_DIR/..``. That will break when the repo is a bare repo. A bare repo has no working directory hence no "repository root". Also it will break when .git is a link instead. – holygeek Sep 14 '15 at 05:06
  • 2
    Figured. Any way to get the repo root under normal usage? For a pre-commit hook which uses the repo as configuration files for a program, for instance? – David Lord Sep 14 '15 at 10:49
  • 3
    This is NOT correct in all cases. See [this blog](http://longair.net/blog/2011/04/09/missing-git-hooks-documentation/). – Ghopper21 Dec 17 '15 at 21:16