{"thread":{"id":"35795","subject":"Bug: relative core.worktree is resolved from symlink and not its target","startedAt":"2014-02-04T10:20:39Z","lastAt":"2014-02-17T12:30:25Z","messageCount":4,"participants":["Daniel Hahler","Duy Nguyen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"234195","messageId":"52F0BEF7.5020600@thequod.de","threadId":"35795","inReplyTo":null,"subject":"Bug: relative core.worktree is resolved from symlink and not its target","fromName":"Daniel Hahler","fromEmail":"genml+git-2014@thequod.de","sentAt":"2014-02-04T10:20:39Z","receivedAt":"2014-02-04T10:20:39Z","isPatch":false,"sender":{"key":"genml+git-2014@thequod.de","avatar":null},"body":"Hi,\n\nwhen using a submodule \"sm\", there is a relative worktree in its config:\n\n   .git/modules/sm/config:\n   [core]\n    worktree = ../../../smworktree\n\ngit-new-worktree (from contrib) symlinks this config the new worktree.\n\nFrom inside the new worktree, git reads the config, but resolves the\nrelative worktree setting based on the symlink's location.\n\nA fix would be to resolve any relative worktree setting based on the\nsymlink target's location (the actual config file), and not from the\nsymlink.\n\nThis is with git version 1.8.5.3.\n\nPlease consider fixing this.\n\n(I know about various workarounds, e.g. copying and adjusting \"config\"\nor manually setting $GIT_WORK_TREE; more relevant discussion would be\nat http://comments.gmane.org/gmane.comp.version-control.git/196019)\n\n\nThanks,\nDaniel.\n\n-- \nhttp://daniel.hahler.de/\n\n"},{"id":"234541","messageId":"20140209090803.GA24578@lanh","threadId":"35795","inReplyTo":"52F0BEF7.5020600@thequod.de","subject":"Re: Bug: relative core.worktree is resolved from symlink and not its target","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2014-02-09T09:08:03Z","receivedAt":"2014-02-09T09:08:03Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Feb 04, 2014 at 11:20:39AM +0100, Daniel Hahler wrote:\n> Hi,\n> \n> when using a submodule \"sm\", there is a relative worktree in its config:\n> \n>    .git/modules/sm/config:\n>    [core]\n>     worktree = ../../../smworktree\n> \n> git-new-worktree (from contrib) symlinks this config the new worktree.\n> \n> From inside the new worktree, git reads the config, but resolves the\n> relative worktree setting based on the symlink's location.\n\nHmm.. core.worktree is relative to $GIT_DIR. Whether \"config\" is a\nsymlink should have no effects.\n\n$ pwd\n/tmp/abc\n$ ls -l .git/config \nlrwxrwxrwx 1 pclouds users 11 Feb  9 15:57 .git/config -> /tmp/config\n$ cat /tmp/config \n[core]\n        repositoryformatversion = 0\n        filemode = true\n        bare = false\n        logallrefupdates = true\n        worktree = ../../worktree\n$ ls -l /tmp/worktree/\ntotal 4\n-rw-r--r-- 1 pclouds users 5 Feb  9 15:59 abc\n$ ~/w/git/git ls-files -o\nabc\n\nMaybe it's something else. Could you produce a small test case?\n\n> A fix would be to resolve any relative worktree setting based on the\n> symlink target's location (the actual config file), and not from the\n> symlink.\n> \n> This is with git version 1.8.5.3.\n--\nDuy\n"},{"id":"234914","messageId":"5301D835.1060301@thequod.de","threadId":"35795","inReplyTo":"20140209090803.GA24578@lanh","subject":"Re: Bug: relative core.worktree is resolved from symlink and not its target","fromName":"Daniel Hahler","fromEmail":"genml+git-2014@thequod.de","sentAt":"2014-02-17T09:36:53Z","receivedAt":"2014-02-17T09:36:53Z","isPatch":false,"sender":{"key":"genml+git-2014@thequod.de","avatar":null},"body":"On 09.02.2014 10:08, Duy Nguyen wrote:\n> On Tue, Feb 04, 2014 at 11:20:39AM +0100, Daniel Hahler wrote:\n\nThanks for looking into this.\n\n>> when using a submodule \"sm\", there is a relative worktree in its config:\n>>\n>>    .git/modules/sm/config:\n>>    [core]\n>>     worktree = ../../../smworktree\n>>\n>> git-new-worktree (from contrib) symlinks this config the new worktree.\n>>\n>> From inside the new worktree, git reads the config, but resolves the\n>> relative worktree setting based on the symlink's location.\n> \n> Hmm.. core.worktree is relative to $GIT_DIR. Whether \"config\" is a\n> symlink should have no effects.\n\nIf \"config\" is a symlink, the relative path for worktree is meant to be\nresolved based on the config file's location, and not from the symlink\n($GIT_DIR).\n\nHere is a test case to reproduce it:\n\n  # Create a submodule repo\n  mkdir /tmp/t-sm\n  cd /tmp/t-sm\n  git init\n  touch foo\n  git add foo\n  git commit -m init\n\n  # Create the root repo\n  mkdir /tmp/t-root\n  cd /tmp/t-root\n  git init\n  mkdir submodules\n  git submodule add /tmp/t-sm submodules/sm\n  git commit -m init\n\n  # Create a new worktree from the submodule\n  cd /tmp/t-root/submodules/sm\n  git-new-workdir . /tmp/new-workdir\n\nThis then fails when checking out:\n+ git checkout -f\nfatal: Could not chdir to '../../../../submodules/sm': No such file or directory\n\n% ls -l /tmp/new-workdir/.git/config \n[…] /tmp/new-workdir/.git/config -> /tmp/t-root/.git/modules/submodules/sm/config\n\n% cat /tmp/new-workdir/.git/config \n[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n\tlogallrefupdates = true\n\tworktree = ../../../../submodules/sm\n\n\nFrom inside of /tmp/new-workdir `git rev-parse --git-dir` fails already\n(with the same \"cannot chdir\" error).\n\nThe problem appears to be that it tries to chdir based on\n/tmp/new-workdir/.git, but should do so based on\n$(readlink -f .git/config).\n\nI recognize that this case is constructed anyway, because even if\n`worktree` would get resolved correctly, it would not be what you'd\nexpect: the point of git-new-workdir is to get a separate worktree, and\nnot use the existing one.\n\nTherefore I see two problems here:\n1. worktree is not resolved correctly by git itself (with .git/config\n   being a symlink)\n2. git-new-workdir should handle this better, e.g. by creating a copy of\n   the \"config\" file with the worktree setting removed and printing a\n   warning about it.\n\nThe workaround appears to be to explicitly set\nGIT_WORK_TREE=/tmp/new-workdir.\n\n\nRegards,\nDaniel.\n\n-- \nhttp://daniel.hahler.de/\n\n"},{"id":"234923","messageId":"CACsJy8B=34f71uW27J_qkq5auqwRdgHrraunon-H0eZvpKDbnA@mail.gmail.com","threadId":"35795","inReplyTo":"5301D835.1060301@thequod.de","subject":"Re: Bug: relative core.worktree is resolved from symlink and not its target","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2014-02-17T12:30:25Z","receivedAt":"2014-02-17T12:30:25Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Feb 17, 2014 at 4:36 PM, Daniel Hahler\n<genml+git-2014@thequod.de> wrote:\n> On 09.02.2014 10:08, Duy Nguyen wrote:\n>> On Tue, Feb 04, 2014 at 11:20:39AM +0100, Daniel Hahler wrote:\n>\n> Thanks for looking into this.\n>\n>>> when using a submodule \"sm\", there is a relative worktree in its config:\n>>>\n>>>    .git/modules/sm/config:\n>>>    [core]\n>>>     worktree = ../../../smworktree\n>>>\n>>> git-new-worktree (from contrib) symlinks this config the new worktree.\n>>>\n>>> From inside the new worktree, git reads the config, but resolves the\n>>> relative worktree setting based on the symlink's location.\n>>\n>> Hmm.. core.worktree is relative to $GIT_DIR. Whether \"config\" is a\n>> symlink should have no effects.\n>\n> If \"config\" is a symlink, the relative path for worktree is meant to be\n> resolved based on the config file's location, and not from the symlink\n> ($GIT_DIR).\n\nI think you started with a wrong assumption. See config.txt it says\n\n-- 8< --\ncore.worktree::\nSet the path to the root of the working tree.\nThis can be overridden by the GIT_WORK_TREE environment\nvariable and the '--work-tree' command line option.\nThe value can be an absolute path or relative to the path to\nthe .git directory, which is either specified by --git-dir\nor GIT_DIR, or automatically discovered.\n-- 8< --\n\nSo I think it fails \"correctly\" (by the book).\n\n> Here is a test case to reproduce it:\n>\n>   # Create a submodule repo\n>   mkdir /tmp/t-sm\n>   cd /tmp/t-sm\n>   git init\n>   touch foo\n>   git add foo\n>   git commit -m init\n>\n>   # Create the root repo\n>   mkdir /tmp/t-root\n>   cd /tmp/t-root\n>   git init\n>   mkdir submodules\n>   git submodule add /tmp/t-sm submodules/sm\n>   git commit -m init\n>\n>   # Create a new worktree from the submodule\n>   cd /tmp/t-root/submodules/sm\n>   git-new-workdir . /tmp/new-workdir\n>\n> This then fails when checking out:\n> + git checkout -f\n> fatal: Could not chdir to '../../../../submodules/sm': No such file or directory\n>\n> % ls -l /tmp/new-workdir/.git/config\n> […] /tmp/new-workdir/.git/config -> /tmp/t-root/.git/modules/submodules/sm/config\n>\n> % cat /tmp/new-workdir/.git/config\n> [core]\n>         repositoryformatversion = 0\n>         filemode = true\n>         bare = false\n>         logallrefupdates = true\n>         worktree = ../../../../submodules/sm\n>\n>\n> From inside of /tmp/new-workdir `git rev-parse --git-dir` fails already\n> (with the same \"cannot chdir\" error).\n>\n> The problem appears to be that it tries to chdir based on\n> /tmp/new-workdir/.git, but should do so based on\n> $(readlink -f .git/config).\n>\n> I recognize that this case is constructed anyway, because even if\n> `worktree` would get resolved correctly, it would not be what you'd\n> expect: the point of git-new-workdir is to get a separate worktree, and\n> not use the existing one.\n>\n> Therefore I see two problems here:\n> 1. worktree is not resolved correctly by git itself (with .git/config\n>    being a symlink)\n> 2. git-new-workdir should handle this better, e.g. by creating a copy of\n>    the \"config\" file with the worktree setting removed and printing a\n>    warning about it.\n>\n> The workaround appears to be to explicitly set\n> GIT_WORK_TREE=/tmp/new-workdir.\n\nNo if you copy \"config\" out then it may be not what you want anymore\n(e.g. new remotes not reflected in new worktree). A better solution is\nmove core.worktree out of \"config\". Notice t-root/submodules/sm is a\nfile that contains the path to the true .git directory. We could have\nstored worktree path in that file instead of in \"config\".\n-- \nDuy\n"}]}