Bug 451619 - jgit daemon doesn't work with bare repositories
Summary: jgit daemon doesn't work with bare repositories
Status: NEW
Alias: None
Product: JGit
Classification: Technology
Component: JGit (show other bugs)
Version: unspecified   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-14 14:42 EST by Thomas Meyer CLA
Modified: 2014-12-01 09:55 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Meyer CLA 2014-11-14 14:42:50 EST
strace reveals:
set_robust_list(0x7f93ec28b9e0, 24)     = 0
gettid()                                = 10782
rt_sigprocmask(SIG_BLOCK, NULL, [QUIT], 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [HUP INT ILL BUS FPE SEGV USR2 TERM], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [QUIT], NULL, 8) = 0
futex(0x7f93bc005d54, FUTEX_WAIT_PRIVATE, 3, NULL) = 0
futex(0x7f93bc005d28, FUTEX_WAIT_PRIVATE, 2, NULL) = 0
futex(0x7f93bc005d28, FUTEX_WAKE_PRIVATE, 1) = 0
sched_getaffinity(10782, 32, {1, 0, 0, 0}) = 32
sched_getaffinity(10782, 32, {1, 0, 0, 0}) = 32
mmap(0x7f93ec18b000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f93ec18b000
mprotect(0x7f93ec18b000, 12288, PROT_NONE) = 0
recvfrom(17, "004fgit-upload-pack /linux.git\0h"..., 8192, 0, NULL, NULL) = 79
stat("/var/lib/git/linux.git/objects", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/var/lib/git/linux.git/refs", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/var/lib/git/linux.git/HEAD", O_RDONLY) = 21
fstat(21, {st_mode=S_IFREG|0644, st_size=146, ...}) = 0
fcntl(21, F_GETFD)                      = 0
fcntl(21, F_SETFD, FD_CLOEXEC)          = 0
stat("/var/lib/git/linux.git/HEAD", {st_mode=S_IFREG|0644, st_size=146, ...}) = 0
read(21, "2c54396e40c79876a7ddfd3231c81eed"..., 146) = 146
read(21, "", 146)                       = 0
close(21)                               = 0
stat("/var/lib/git/linux.git/.git/objects", 0x7f93ec28a4d0) = -1 ENOENT (No such file or directory)
stat("/var/lib/git/linux.git.git/objects", 0x7f93ec28a4d0) = -1 ENOENT (No such file or directory)
dup2(15, 17)                            = 17
close(17)                               = 0
gettimeofday({1415993826, 101755}, NULL) = 0
gettimeofday({1415993826, 101786}, NULL) = 0
futex(0x7f93e806b754, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7f93e806b750, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7f93bc005d54, FUTEX_WAIT_PRIVATE, 5, NULL) = 0
futex(0x7f93bc005d28, FUTEX_WAIT_PRIVATE, 2, NULL) = 0
futex(0x7f93bc005d28, FUTEX_WAKE_PRIVATE, 1) = 0
mmap(0x7f93ec18b000, 12288, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7f93ec18b000
gettimeofday({1415993826, 102456}, NULL) = 0
rt_sigprocmask(SIG_SETMASK, [QUIT], NULL, 8) = 0
madvise(0x7f93ec18b000, 1028096, MADV_DONTNEED) = 0
_exit(0)                                = ?
+++ exited with 0 +++


/var/lib/git/linux.git/.git/objects -> correct would be /var/lib/git/linux.git/objects/

$ jgit --version
jgit version 3.3.2.201404171909-r
Comment 1 Thomas Meyer CLA 2014-11-14 14:56:37 EST
Same for org.eclipse.jgit.http.server.GitServlet:

version:
3.4.1.201406201815

stat("/var/lib/git/linux.git/HEAD", {st_mode=S_IFREG|0644, st_size=146, ...}) = 0
read(81, "2c54396e40c79876a7ddfd3231c81eed"..., 146) = 146
read(81, "", 146)                       = 0
close(81)                               = 0
lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git/linux.git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git/linux.git/.git", 0x7fa9c3af5c50) = -1 ENOENT (No such file or directory)
lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git/linux.git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git/linux.git/.git", 0x7fa9c3af5c50) = -1 ENOENT (No such file or directory)
lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git/linux.git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
gettimeofday({1415994770, 332512}, NULL) = 0
stat("/var/lib/git/linux.git/.git/objects", 0x7fa9c3af87b0) = -1 ENOENT (No such file or directory)
lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git/linux.git.git", 0x7fa9c3af5c50) = -1 ENOENT (No such file or directory)
lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git/linux.git.git", 0x7fa9c3af5c50) = -1 ENOENT (No such file or directory)
lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/var/lib/git", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
gettimeofday({1415994770, 332869}, NULL) = 0
stat("/var/lib/git/linux.git.git/objects", 0x7fa9c3af87b0) = -1 ENOENT (No such file or directory)
writev(73, [{"HTTP/1.1 200 OK\r\nExpires: Fri, 0"..., 241}, {"001e# service=git-upload-pack\n00"..., 66}], 2) = 307
gettimeofday({1415994770, 333307}, NULL) = 0
futex(0x7fa9e84e13b4, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fa9e84e13b0, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
futex(0x7fa9e84e1388, FUTEX_WAKE_PRIVATE, 1) = 1
read(73, 0x7fa9e861f980, 8192)          = -1 EAGAIN (Resource temporarily unavailable)
read(73, 0x7fa9e861f980, 8192)          = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1415994770, 334249}, NULL) = 0
clock_gettime(CLOCK_MONOTONIC, {248604, 57369300}) = 0
clock_gettime(CLOCK_MONOTONIC, {248604, 57388387}) = 0
futex(0x7fa9e84d1414, FUTEX_WAIT_BITSET_PRIVATE, 3, {248664, 57388387}, ffffffff <detached ...>
Comment 2 Christian Halstrick CLA 2014-11-17 01:54:17 EST
Does this still fail with the latest build of jgit [1]? I fixed something in https://git.eclipse.org/r/#/c/36128/.

[1] http://download.eclipse.org/egit/updates-nightly
Comment 3 Thomas Meyer CLA 2014-11-17 02:28:00 EST
Hi,

Either I did something wrong while testing the latest jgit version, I did build it directly from git, or the said patch doesn't work.

I'll try the nightly builds.
Comment 4 Christian Halstrick CLA 2014-11-17 05:13:43 EST
I wrote the patch for a different scenario without knowing about this bug. So, only 50% chance that the fix solves your problem.
Comment 5 Christian Halstrick CLA 2014-11-19 09:13:54 EST
for me the daemon work on bare repos even before my fix. Check this out:

> wget -q -O jgit.sh https://repo.eclipse.org/content/groups/releases//org/eclipse/jgit/org.eclipse.jgit.pgm/3.5.2.201411120430-r/org.eclipse.jgit.pgm-3.5.2.201411120430-r.sh
> chmod +x jgit.sh
> git clone -q --bare https://github.com/chalstrick/dondalfi.git server-root/dondalfi.git
> ls server-root/dondalfi.git/
branches  config  description  HEAD  hooks  info  objects  packed-refs  refs
> ./jgit.sh daemon --export-all server-root/ &
[1] 12184
> Exporting /tmp/qq/server-root
Listening on 0.0.0.0/0.0.0.0:9418

> git clone git://localhost:9418/dondalfi.git
Cloning into 'dondalfi'...
remote: Counting objects: 332, done
remote: Finding sources: 100% (332/332)
remote: Getting sizes: 100% (201/201)
Receiving objects: 100% (332/332), 20.44 KiB | 0 bytes/s, done.
Resolving deltas: 100% (86/86), done.
remote: Total 332 (delta 86), reused 332 (delta 86)
Checking connectivity... done.
Comment 6 Thomas Meyer CLA 2014-11-20 05:23:21 EST
Hi,

yes you are right!

the problem arose because I did fetch the bare git repo with this command:

/usr/bin/jgit --git-dir /var/lib/git/linux.git fetch origin 'refs/heads/*:refs/remotes/origin/*'

after the fetch i did copy the FETCH_HEAD unconditionally to the HEAD file:
/usr/bin/mv /var/lib/git/linux.git/FETCH_HEAD /var/lib/git/linux.git/HEAD

as it turns out the git-daemon seems not to have a problem with a HEAD file containing a string like:
"sha1       not-to-merge   URL-of-remote"

It happily servers the first sha1 given in the head file (do I actually need to update HEAD after a git fetch on a bare repository?)

but jgit daemon fails to work correctly if the HEAD file contains above string.
jgit daemon works correctly if the HEAD file only contains a sha1 an nothing else.

so, what do you think? bug or feature? :-)
Comment 7 Christian Halstrick CLA 2014-11-21 03:33:37 EST
I think copying FETCH_HEAD to HEAD is not a good idea. FETCH_HEAD can contain multiple lines (all the HEADs fetched). Why don't you "git reset FETCH_HEAD" instead of manipulating the files manually. If that also fails we definitely have a bug. If it works then I don't care too much that jgit behaves differently von cgit on strange HEAD files.
Comment 8 Thomas Meyer CLA 2014-11-29 08:08:31 EST
Hi,

I tried your suggestion, but I get this:

$ cat FETCH_HEAD 
3314bf6ba2ac8f1a2dd0d55a980835a258f1a45d		https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux

$ git reset FETCH_HEAD
fatal: mixed reset is not allowed in a bare repository

I now changed my automatic fetch service to do this:

1.) Always fetch all remotes:
/usr/bin/jgit --git-dir ${GIT_DIR}/%i/ fetch origin 'refs/heads/*:refs/remotes/origin/*'

2.) unconditionally copy the first sha1 from the FETCH_HEAD file to the HEAD file, hopefully the first entry corresponds to remote master..
/usr/bin/dd if=${GIT_DIR}/%i/FETCH_HEAD of=${GIT_DIR}/%i/HEAD bs=40 count=1
Comment 9 Christian Halstrick CLA 2014-12-01 09:55:06 EST
Why don't: 
  cp ${GIT_DIR}/%i/refs/remotes/origin/master ${GIT_DIR}/%i/HEAD