Hi Bob, On Sat, 28 Jan 2017, Bob Proulx wrote: > And the server side says: > > [26071] Request upload-pack for '/test-project.git' > [26071] fatal: Unable to create temporary file '/srv/git/test-project.git/shallow_xKwnvZ': Permission denied > [26055] [26071] Disconnected (with error) Assuming that you can rebuild your Git with debug symbols and without optimization (simply remove the -O2 from CFLAGS in the Makefile, I never had any luck with single-stepping in gdb when compiled with -O2), you could attach gdb to the git-daemon and/or upload-pack process. Setting a breakpoint on die_builtin in the failing process should give you a good idea why things are failing, at least looking at the stacktrace. A few more tidbits from a cursory look at the Git source code with `git grep` and the likes: - that error message comes from shallow.c's setup_temporary_shallow() function - that function is only called from fetch-pack and receive-pack, neither of which should be called by upload-pack, so it is a puzzle - adding a test case to t5570-git-daemon.sh that tests specifically your described scenario seems *not* to fail: -- snip -- diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh index 225a022e8a..0256c9aded 100755 --- a/t/t5570-git-daemon.sh +++ b/t/t5570-git-daemon.sh @@ -186,5 +186,17 @@ test_expect_success 'hostname cannot break out of directory' ' git clone --bare "$GIT_DAEMON_URL/escape.git" tmp.git ' +test_expect_success POSIXPERM 'shallow clone from read-only server' ' + test_when_finished "rm -rf tmp.git" && + repo="$GIT_DAEMON_DOCUMENT_ROOT_PATH/readonly.git" && + git init --bare "$repo" && + git push "$repo" HEAD && + >"$repo"/git-daemon-export-ok && + chmod a-w "$repo" && + test_must_fail \ + env GIT_OVERRIDE_VIRTUAL_HOST=.. \ + git clone --depth 1 "$GIT_DAEMON_URL/readonly.git" tmp.git +' + stop_git_daemon test_done -- snap -- - I even modified t/lib-git-daemon.sh to start the daemon as `nobody` and kill it as `root`, and I won't share that patch because it is as ugly, but *even then* the test succeeded. So my suspicion is that the repository you try to serve may already be shallow, or something else funky is going on that has not been included in your report. The most direct way to get to the bottom of this may be to do something like this: -- snip -- diff --git a/shallow.c b/shallow.c index 11f7dde9d9..30f5c96d50 100644 --- a/shallow.c +++ b/shallow.c @@ -288,12 +288,18 @@ int write_shallow_commits(struct strbuf *out, int use_pack_protocol, static struct tempfile temporary_shallow; +static int debug_me; + const char *setup_temporary_shallow(const struct sha1_array *extra) { struct strbuf sb = STRBUF_INIT; int fd; if (write_shallow_commits(&sb, 0, extra)) { +error("About to create shallow_XXXXXX: pid = %d", getpid()); +while (!debug_me) { + sleep(1); +} fd = xmks_tempfile(&temporary_shallow, git_path("shallow_XXXXXX")); if (write_in_full(fd, sb.buf, sb.len) != sb.len) -- snap -- Then let it run, wait for the error message "About to create shallow_XXXXXX" and then attach with a gdb started as nobody via `attach <pid>` to see the stack trace. That should give you an idea where that code path is hit (unexpectedly). Ciao, Johannes