Re: Bug: relative core.worktree is resolved from symlink and not its target
- From
Duy Nguyen <pclouds@gmail.com>
- Date
- Feb 17, 2014, 12:30 UTC
- Message-ID
- <CACsJy8B=34f71uW27J_qkq5auqwRdgHrraunon-H0eZvpKDbnA@mail.gmail.com>
- In-Reply-To
- <5301D835.1060301@thequod.de>
On Mon, Feb 17, 2014 at 4:36 PM, Daniel Hahler <genml+git-2014@thequod.de> wrote:
Show 22 quoted lines
> On 09.02.2014 10:08, Duy Nguyen wrote: >> On Tue, Feb 04, 2014 at 11:20:39AM +0100, Daniel Hahler wrote: > > Thanks for looking into this. > >>> when using a submodule "sm", there is a relative worktree in its config: >>> >>> .git/modules/sm/config: >>> [core] >>> worktree = ../../../smworktree >>> >>> git-new-worktree (from contrib) symlinks this config the new worktree. >>> >>> From inside the new worktree, git reads the config, but resolves the >>> relative worktree setting based on the symlink's location. >> >> Hmm.. core.worktree is relative to $GIT_DIR. Whether "config" is a >> symlink should have no effects. > > If "config" is a symlink, the relative path for worktree is meant to be > resolved based on the config file's location, and not from the symlink > ($GIT_DIR).
I think you started with a wrong assumption. See config.txt it says
-- 8< -- core.worktree:: Set the path to the root of the working tree. This can be overridden by the GIT_WORK_TREE environment variable and the '--work-tree' command line option. The value can be an absolute path or relative to the path to the .git directory, which is either specified by --git-dir or GIT_DIR, or automatically discovered. -- 8< --
So I think it fails "correctly" (by the book).
Show 59 quoted lines
> Here is a test case to reproduce it: > > # Create a submodule repo > mkdir /tmp/t-sm > cd /tmp/t-sm > git init > touch foo > git add foo > git commit -m init > > # Create the root repo > mkdir /tmp/t-root > cd /tmp/t-root > git init > mkdir submodules > git submodule add /tmp/t-sm submodules/sm > git commit -m init > > # Create a new worktree from the submodule > cd /tmp/t-root/submodules/sm > git-new-workdir . /tmp/new-workdir > > This then fails when checking out: > + git checkout -f > fatal: Could not chdir to '../../../../submodules/sm': No such file or directory > > % ls -l /tmp/new-workdir/.git/config > […] /tmp/new-workdir/.git/config -> /tmp/t-root/.git/modules/submodules/sm/config > > % cat /tmp/new-workdir/.git/config > [core] > repositoryformatversion = 0 > filemode = true > bare = false > logallrefupdates = true > worktree = ../../../../submodules/sm > > > From inside of /tmp/new-workdir `git rev-parse --git-dir` fails already > (with the same "cannot chdir" error). > > The problem appears to be that it tries to chdir based on > /tmp/new-workdir/.git, but should do so based on > $(readlink -f .git/config). > > I recognize that this case is constructed anyway, because even if > `worktree` would get resolved correctly, it would not be what you'd > expect: the point of git-new-workdir is to get a separate worktree, and > not use the existing one. > > Therefore I see two problems here: > 1. worktree is not resolved correctly by git itself (with .git/config > being a symlink) > 2. git-new-workdir should handle this better, e.g. by creating a copy of > the "config" file with the worktree setting removed and printing a > warning about it. > > The workaround appears to be to explicitly set > GIT_WORK_TREE=/tmp/new-workdir.
No if you copy "config" out then it may be not what you want anymore (e.g. new remotes not reflected in new worktree). A better solution is move core.worktree out of "config". Notice t-root/submodules/sm is a file that contains the path to the true .git directory. We could have stored worktree path in that file instead of in "config".
-- Duy