Re: Unexpected working directory in post-receive hook in non-bare repository
- Date: Mon, 10 Apr 2017 13:13:15 +0200
- From: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
- Subject: Re: Unexpected working directory in post-receive hook in non-bare repository
On Sun, Apr 9, 2017 at 3:01 PM, Simon Ruderich <simon@xxxxxxxxxxxx> wrote:
> The following snippet reproduces the issue for me (note the
> remote: line in its output):
> git --version
> rm -rf a b
> git init a
> cd a
> echo first >data
> git add data
> git commit -m initial
> cat >>.git/hooks/post-receive <<EOF
> chmod +x .git/hooks/post-receive
> cd ..
> git clone a b
> cd b
> echo second >>data
> git add data
> git commit -m test
> git push origin master:not-master
> According to man githooks "Before Git invokes a hook, it changes
> its working directory to either the root of the working tree in a
> non-bare repository, [...]". In this case "a" is non-bare and I
> expected the command to be run in the working tree; but instead
> it's run inside .git. (This caused some confusion in my case
> because I ran "git merge" in the hook which put files in the .git
> directory and I didn't notice it at first. I know running merge
> in receive-hooks is "bad practice" but it works fine in my
> The same happens for all hooks executed by git-receive-pack:
> pre-receive, update, post-receive, post-update.
> Is this a documentation issue or unexpected behavior?
It's a documentation issue I think. I added this change to the
githooks manpage last year in 49fa52fd00, but didn't think about the
case of pushing into non-bare repositories. The behavior itself hasn't
changed in a long time.
I wonder how to phrase this so that it's unambiguous & simply states a
general rule. I.e. instead of:
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.
Can we say as we do now that:
* All hooks regardless of type in bare repos execute in the bare repo
* If you have a working tree hooks use that
* Working trees are ignored by any hooks invoked on your behalf during a push.
Some ad-hoc testing reveals that this rule also goes for the
push-to-checkout hook. Should it? Wouldn't it be more useful if it
broke the pattern, since it's dealing with the working tree on the
other side? Junio?