#399041 please deal with .git/.git directories a bit more gracefully

Package:
git
Source:
git
Description:
fast, scalable, distributed revision control system
Submitter:
Pierre Habouzit
Date:
2010-09-27 19:15:27 UTC
Severity:
minor
#399041#5
Date:
2006-11-17 10:39:20 UTC
From:
To:
  git ls-remote does not works like before (it seems it bails out when
you give him $GIT_DIR as an argument) and breaks many commands,
including gitk (but other fails also).

  this impedes git usability a *lot* as gitk is really a central tool to
keep track of what's going on for quite complicated projects.


  instead of $GIT_DIR git ls-remote seems to want $GIT_DIR/.. wich is
quite incompatible with an external .git as well anyway.

#399041#10
Date:
2006-11-17 12:29:05 UTC
From:
To:
Hi Pierre, I cannot reproduce this from your description.  Also
git-ls-remote.sh didn't change since 1.4.3.  Can you please paste the
exact command you run and the error message you receive?

Thanks, Gerrit.

#399041#17
Date:
2006-11-17 15:49:49 UTC
From:
To:

#399041#22
Date:
2006-11-17 15:24:07 UTC
From:
To:
severity 399041 important
thanks


  Oh sorry, I forgot to do that.

  I've repositories created with git-svn (maybe that's a reason, in fact
it seems it work with other repositories). and then when I run gitk --all, it
bails out and says:

    $ gitk --all
    Error in startup script: fatal: '.git': unable to chdir or not a git archive
    fatal: unexpected EOF
    Failed to find remote refs
        while executing
    "close $refd"
        (procedure "readrefs" line 47)
        invoked from within
    "readrefs"
        (file "/usr/bin/gitk" line 6281)

  when I hack gitk around line 312 to make it do "git ls-remote [gitdir]/.."
it works as it's supposed to, hence me suposing that it was git ls-remote
fault. the fact that it works with other repos that are pure git ones show
that I'm actually wrong, so I've downgraded the severity accordingly (it only
renders the package unusable for /some/ uses of it :)).



  Further checks shows taht in a "pure git" repository of mine I can do:

    $ git ls-remote .git
    b4bf40ddf386c8b0137c967448b60c104e624767        HEAD
    b4bf40ddf386c8b0137c967448b60c104e624767        refs/heads/master
    32b109474d5c1b57ab6a759cb15e9d27007546f1        refs/heads/origin

  whereas in a git-svn one:

    $ git ls-remote .git
    fatal: '.git': unable to chdir or not a git archive
    fatal: unexpected EOF
    Failed to find remote refs

  Sorry I did not checked a "pure" git repo first, I only did the git
ls-remote in a git-svn repo before. So I'm not really sure where the bug is
anymore, git-svn may be the good candidate after all :)

CHeers,

#399041#27
Date:
2006-11-20 15:34:55 UTC
From:
To:
Thanks, unfortunately I still fail to reproduce it.  This is what I did:

 $ git-svn init svn://bruce-guenter.dyndns.org/bcron/trunk bcron
 $ cd bcron/
 $ git ls-remote .git
 $ git-svn fetch
 [...]
 $ git ls-remote .git
 ba21842a7cee7fa7c6a10e589574c643b74a7e60        HEAD
 ba21842a7cee7fa7c6a10e589574c643b74a7e60        refs/heads/master
 ba21842a7cee7fa7c6a10e589574c643b74a7e60        refs/remotes/git-svn
 $

From the error messages you posted, it looks like it's git-upload-pack,
called by git-ls-remote through git-peek-remote, that fails, because it
cannot identify .git as a git repository.  What git-upload-pack checks
(path.c) is .git, .git/objects, and .git/refs.  Do these directories
exist in your repo?:

 $ ls -ld .git .git/objects .git/refs

Regards, Gerrit.

#399041#32
Date:
2006-11-20 18:47:18 UTC
From:
To:
  damn :|

  yes I have'em.
  FWIW:

    $ ls -ld .git .git/objects .git/refs
    drwxr-xr-x  10 madcoder madcoder 4096 2006-11-20 13:19 .git
    drwxr-xr-x 260 madcoder madcoder 4096 2006-11-20 13:19 .git/objects
    drwxr-xr-x   5 madcoder madcoder 4096 2006-10-15 00:05 .git/refs
    $ find .git/refs
    .git/refs
    .git/refs/tags
    .git/refs/heads
    .git/refs/heads/master
    .git/refs/remotes
    .git/refs/remotes/git-svn

  and as I just did a git repack -a -d + prune, I just have:

     $ find .git/objects
    .git/objects
    .git/objects/info
    .git/objects/info/packs
    .git/objects/pack
    .git/objects/pack/pack-2702b57b5820cb92a98c71098a1591cccdc2670b.pack
    .git/objects/pack/pack-2702b57b5820cb92a98c71098a1591cccdc2670b.idx

  what's really curious is that any other git command I use (and I don't
use all'of em obviously ;p) work flawlessly. Maybe what would be worth
mentionning is that I use it over NFS ? but I've cp -a'ed the repository
to another place on a real disk, and it still did not work.

  what I've discovered, is that my .git/remotes/ is empty though and I
must say I've really no idea why it's empty, I'm positive about the fact
that I never played with that file :|

#399041#37
Date:
2006-11-21 14:27:04 UTC
From:
To:
Hm, can you please check the following in your git-svn repository?:

 $ git-ls-remote .git/

and if there's any difference, can you run?:

 $ sh -x /usr/bin/git-ls-remote .git
and
 $ sh -x /usr/bin/git-ls-remote .git/

It's strange that git-repack works for, it does the same checks as
git-peek-remote, which I think is giving the error.

There a git version 1.4.4 in incoming, can you check this?  Do you know
which version of git-svn you used to create the repository?

Regards, Gerrit.

#399041#42
Date:
2006-11-21 16:01:50 UTC
From:
To:
  fails as well:

  $ git-ls-remote .git/
  fatal: '.git': unable to chdir or not a git archive
  fatal: unexpected EOF
  Failed to find remote refs

  I confirm git-peek-remote is the culprit:

  $ git-peek-remote .git/
  fatal: '.git': unable to chdir or not a git archive
  fatal: unexpected EOF
  $ git-peek-remote .git
  fatal: '.git': unable to chdir or not a git archive
  fatal: unexpected EOF
BTS says: 1:1.4.2.3-1


  ===================
  now that I know git-peek-remote is the culprit, I've straced it a bit.
git-peek-remotes works properly, that's a subcommand it runs that make
it fails. at some point, git-peek-remote clones itself, and git-upload-pack is
the one that fails with some curious errors (see at the end, it searches for .git/.git/ ?!)

**** SNIP ****
clone(Process 32619 attached (waiting for parent)
Process 32619 resumed (parent 32617 ready)
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b3306cafd10) = 32619
**** SNIP ****
[pid 32619] execve("/bin/sh", ["sh", "-c", "git-upload-pack \'.git\'"], [/* 50 vars */]) = 0
**** SNIP ****
[pid 32619] execve("/usr/bin/git-upload-pack", ["git-upload-pack", ".git"], [/* 49 vars */]) = 0
**** SNIP ****
[pid 32619] execve("/usr/bin/git-upload-pack", ["git-upload-pack", ".git"], [/* 49 vars */]) = 0
[pid 32619] uname({sys="Linux", node="mad", ...}) = 0
[pid 32619] brk(0)                      = 0x52b000
[pid 32619] access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
[pid 32619] mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b7e909c9000
[pid 32619] access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
[pid 32619] open("/etc/ld.so.cache", O_RDONLY) = 3
[pid 32619] fstat(3, {st_mode=S_IFREG|0644, st_size=68546, ...}) = 0
[pid 32619] mmap(NULL, 68546, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2b7e909cb000
[pid 32619] close(3)                    = 0
[pid 32619] access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
[pid 32619] open("/usr/lib/libz.so.1", O_RDONLY) = 3
[pid 32619] read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P @\0010"..., 640) = 640
[pid 32619] fstat(3, {st_mode=S_IFREG|0644, st_size=92216, ...}) = 0
[pid 32619] mmap(0x3001400000, 1136808, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3001400000
[pid 32619] mprotect(0x3001416000, 1046696, PROT_NONE) = 0
[pid 32619] mmap(0x3001515000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x3001515000
[pid 32619] close(3)                    = 0
[pid 32619] access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
[pid 32619] open("/lib/libc.so.6", O_RDONLY) = 3
[pid 32619] read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\305"..., 640) = 640
[pid 32619] lseek(3, 624, SEEK_SET)     = 624
[pid 32619] read(3, "\4\0\0\0\20\0\0\0\1\0\0\0GNU\0\0\0\0\0\2\0\0\0\6\0\0\0"..., 32) = 32
[pid 32619] fstat(3, {st_mode=S_IFREG|0755, st_size=1286312, ...}) = 0
[pid 32619] mmap(NULL, 2344904, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b7e90aca000
[pid 32619] mprotect(0x2b7e90beb000, 1161160, PROT_NONE) = 0
[pid 32619] mmap(0x2b7e90ceb000, 98304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x121000) = 0x2b7e90ceb000
[pid 32619] mmap(0x2b7e90d03000, 14280, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2b7e90d03000
[pid 32619] close(3)                    = 0
[pid 32619] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b7e90d07000
[pid 32619] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b7e90d08000
[pid 32619] mprotect(0x2b7e90ceb000, 86016, PROT_READ) = 0
[pid 32619] arch_prctl(ARCH_SET_FS, 0x2b7e90d07c80) = 0
[pid 32619] munmap(0x2b7e909cb000, 68546) = 0
[pid 32619] access(".git.git/.git", F_OK) = -1 ENOENT (No such file or directory)
[pid 32619] access(".git/.git", F_OK)   = 0
[pid 32619] chdir(".git/.git")          = 0
[pid 32619] access("objects", X_OK)     = -1 ENOENT (No such file or directory)
[pid 32619] write(2, "fatal: ", 7fatal: )      = 7
[pid 32619] write(2, "\'.git\': unable to chdir or not a"..., 44'.git': unable to chdir or not a git archive) = 44
[pid 32619] write(2, "\n", 1
)           = 1
[pid 32619] exit_group(128)             = ?
Process 32619 detached
<... read resumed> "", 4)               = 0
--- SIGCHLD (Child exited) @ 0 (0) ---

#399041#47
Date:
2006-11-21 16:43:18 UTC
From:
To:
severity 399041 normal
quit

Ah, for some reason you have a subdirectory .git/ in your .git/
directory, and that confuses git-upload-pack (path.c:enter_repro()).

 $ rmdir .git/.git

should fix it, but git could be improved to catch this, or at least
give a better error message.

Regards, Gerrit.

#399041#54
Date:
2006-11-21 23:11:29 UTC
From:
To:
  wow, that was it, I never thought of doing an ls -a there :)

  interestingly enough:

    $  find .git/.git
    .git/.git
    .git/.git/svn
    .git/.git/svn/git-svn
    .git/.git/svn/git-svn/.rev_db

  I can confirm that it solves the problme. thanks for the very good
catch !

  I'm ok with that bug beeing closed, or maybe renamed into a 'minor
bug' retitled "please deal with .git/.git directories a bit more
gracefully ;)

#399041#63
Date:
2009-04-03 06:45:47 UTC
From:
To:
found 399041 1:1.6.2-1
thanks

Hi,

Some notes:

 1. "git svn init" from a .git directory still creates .git/.git
instead of acting like "git --bare svn init".
 2. Similarly for "git init".
 3. "git ls-remote .git", "git clone .git", etc. are still unhelpful,
so bare repositories with .git subdir are still unusable.
 4. In git 1.5.0-rc0 (commit ef0a89a "Provide more meaningful output
from 'git init-db'."), git init and git svn init learned to tell what
GIT_DIR they are using, so problems 1 and 2 above are harmless now.
 5. In git 1.5.0-rc4 the gitk issue was fixed by using the more robust
'show-ref' command (commit 0f57a3 "gitk: Use show-ref instead of
ls-remote").

Making a .git/.git directory by accident is difficult, but if you do
it, you won't know until you try to use your .git directory as a
remote repo.

Most git commands (like git show-ref) use setup_git_directory_gently,
so they test .git, .git/, ./, etc in turn for objects/, refs/, or
valid HEAD.  But upload-pack uses enter_repo.  So: we should either
change upload-pack to not bail out on the first non-git directory it
finds, or factor out a better helper function from
setup_git_directory_gently.  enter_repo repeats the logic from
is_git_directory already.

But I could be speaking total nonsense --- it's hard to tell at this
hour. Hope I haven't wasted too much time with my speculation -- I
better sleep before I look into this further.

Regards,
Jonathan