Getting this when a git push to git:// runs the pre-receive hook which is set up by the git_test_receive_wrapper:

remote: fatal: Not a git repository (or any of the parent directories): .git
remote: 'git log --pretty=raw --raw --abbrev=40 --always -c -r 21161ba01a093534ef97188eae098d83554dbcc6..73820a1d7e76318d8b1ac23e1c6d47e50a3e8ca2 --no-renames -- .' failed: 
To git://
 ! [remote rejected]     master -> master (pre-receive hook declined)
error: failed to push some refs to 'git://'

Relevant code:

            # Avoid chdir when running git here, because the changes
            # are in the master git repo, not the srcdir repo.
            # (Also, if a subdir is involved, we don't want to chdir to
            # it and only see changes in it.)
            # The pre-receive hook already puts us in the right place.
            push @rets, git_parse_changes('.', 0, git_commit_info('.', $oldrev."..".$newrev));

This is with git 1:2.11.0-3+deb9u2 on debian stable, ikiwiki 3.20171002.

Tossing a call to pwd in there, it's at the top of the master (bare) git repository, which seems right. I can do a similar git log at that location manually (using different revs). Looking at the environment at that point (in another wiki that has the same problem), I found only these git env vars:

remote: GIT_ALTERNATE_OBJECT_DIRECTORIES=/home/b-joeyh/source.git/./objects
remote: GIT_OBJECT_DIRECTORY=/home/b-joeyh/source.git/./objects/incoming-hVfXvD
remote: GIT_QUARANTINE_PATH=/home/b-joeyh/source.git/./objects/incoming-hVfXvD

[[!commit 6fb43c29f63b85c3424520819427903e5a204426]] is relevant to that, and I guess it didn't fully solve the problem. --Joey

Stracing git-daemon -f I noticed this:

[pid 22616] lstat64("/home/b-ikiwiki/source.git/HEAD", {st_mode=S_IFREG|0664, st_size=23, ...}) = 0
[pid 22616] openat(AT_FDCWD, "/home/b-ikiwiki/source.git/HEAD", O_RDONLY|O_LARGEFILE) = 3
[pid 22616] read(3, "ref: refs/heads/master\n", 255) = 23
[pid 22616] read(3, "", 232)            = 0
[pid 22616] close(3)                    = 0
[pid 22616] lstat64("/home/b-ikiwiki/source.git/commondir", 0xbf83896c) = -1 ENOENT (No such file or directory)
[pid 22616] access("/home/b-ikiwiki/source.git/./objects/incoming-gXNPXm", X_OK) = -1 EACCES (Permission denied)
[pid 22616] stat64("/home/b-ikiwiki", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

So the git diff is in the right cwd, it gets as far as reading HEAD. But then this permissions error on this incoming directory happens, and it then seems to give up and search for a different git repo to use in the parent directory (and all the way up to root).

The directory is created by git earlier in the strace:

[pid 22559] mkdir("./objects/incoming-gXNPXm", 0700) = 0

And here's how it looks:

drwx------+ 7 ikiwiki-anon ikiwiki-anon 4096 Jun 14 00:22 incoming-y6a8pe/

And I think that's the problem, by the time ikiwiki runs it's switched away from the ikiwiki-anon user that git-daemon uses, and over to the site user. Which can't read that.

source.git has an ACL set to let ikiwiki-anon write to it.

ikisite:        eval { shell("setfacl", "-R", "-m", "d:g:$config{gitdaemonuser}:rwX,d:g:$user:rwX,g:$config{gitdaemonuser}:rwX,g:$user:rwX", "$home/source.git") };

Can this ACL be adjusted so that all directories created under it will be readable by the site user (b-ikiwiki)? I don't know ACLs very well.

Alternatively, GIT_QUARANTINE_PATH is set to the directory, so the C wrapper could fix up its permissions. The wrapper is suid, so either would need to switch user ID back to ikiwiki-anon, if that's allowed, or there would need to be an outer wrapper that's not suid (just a shell script would work) that then runs the regular suid wrapper.

This was not a bug in ikiwiki, but ikiwiki-hosting. Fixed there (using the wrapper wrapper approach). done --Joey