git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Versioning configuration files on a server: fatal: Unable to create '//etc/.git/index.lock': No such file or directory

From
Matthijs Kooijman <matthijs@stdin.nl>
Date
Nov 18, 2010, 20:36 UTC
Message-ID
<20101118203617.GH22067@login.drsnuggles.stderr.nl>
In-Reply-To
<20101118171751.GG22067@login.drsnuggles.stderr.nl>
Hi folks,
Show 5 quoted lines
> > I think 490544b (get_cwd_relative(): do not misinterpret suffix as
> > subdirectory - 2010-05-22) causes it. Haven't fully understood what's
> > going on in that function though :P
> Seems you're right. I just reverted this commit and the problem seems to
> go away.

A bit more gdb'ing with -O0, I found the following. get_cwd_relative is called with dir="/". The cwd is "/etc". The stack looks like:

#0 get_relative_cwd (buffer=0x7a44c0 "/etc", size=4096, dir=0x7b1041 "") at dir.c:961 #1 0x00000000004dfdf1 in setup_git_directory () at setup.c:612 #2 0x0000000000404f69 in run_builtin (p=0x75ea10, argc=2, argv=0x7fffffffc918) at git.c:257 #3 0x00000000004051e3 in handle_internal_command (argc=2, argv=0x7fffffffc918) at git.c:431 #4 0x000000000040538a in main (argc=2, argv=0x7fffffffc918) at git.c:516

After the following code runs:
    while (*dir && *dir == *cwd) {
	    dir++; 
	    cwd++;
    }
I have dir="" and cwd="etc". Then the following code runs:
    switch (*cwd) {
    case '\0':
	    return cwd;
    case '/':
	    return cwd + 1;
    default:
	    return NULL;
    }
Since *cwd='e', it returns NULL.
The old code (before 490544b) was:
   if (*cwd == '/')
	   return cwd + 1;
   return cwd;
So this would return "etc".

So, that's what is happens. I think this happens because get_relative_cwd expects dir to not contain a trailing slash. Normally, there is no trailing slash, but in the special case of dir="/" there is (sort of) a trailing slash.

I'm not completely sure how to fix this. Looking at 72ec8ba (Support working directory located at root - 2010-02-14), perhaps something like this?

diff --git a/dir.c b/dir.c
index d1e5e5e..5408db9 100644
--- a/dir.c
+++ b/dir.c
@@ -943,6 +943,7 @@ int file_exists(const char *f)
 char *get_relative_cwd(char *buffer, int size, const char *dir)
 {
        char *cwd = buffer;
+       size_t len, root_len;
 
        if (!dir)
                return NULL;
@@ -952,6 +953,15 @@ char *get_relative_cwd(char *buffer, int size, const char *dir)
        if (!is_absolute_path(dir))
                dir = make_absolute_path(dir);
 
+       len = strlen(dir);
+       root_len = offset_1st_component(dir);
+
+       if (root_len >= len) {
+           /* dir is the filesystem root, so the cwd is always inside */
+           root_len = offset_1st_component(cwd);
+           return cwd + root_len;
+       }
+
        while (*dir && *dir == *cwd) {
                dir++;
                cwd++;

I'm not sure how this stuff really works, though. I think this works for *nix,
but I'm unsure about Windows.

Gr.

Matthijs
Previous: Matthijs Kooijman
Message 8 of 8 in “Versioning configuration files on a server: fatal: Unable to create '//etc/.git/index.lock': No such file or directory”
  1. Albert StrasheimNov 17, 2010
  2. Matthijs KooijmanNov 17, 2010
  3. Matthijs KooijmanNov 18, 2010
  4. Santi BéjarNov 18, 2010
  5. Nguyen Thai Ngoc DuyNov 18, 2010
  6. Nguyen Thai Ngoc DuyNov 18, 2010
  7. Matthijs KooijmanNov 18, 2010
  8. Matthijs KooijmanNov 18, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.