On Mon, Feb 17, 2014 at 4:36 PM, Daniel Hahler <genml+git-2014@xxxxxxxxxx> wrote: > 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). > 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html