git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Bug: relative core.worktree is resolved from symlink and not its target
@ 2014-02-04 10:20 Daniel Hahler
  2014-02-09  9:08 ` Duy Nguyen
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Hahler @ 2014-02-04 10:20 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 856 bytes --]

Hi,

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.

A fix would be to resolve any relative worktree setting based on the
symlink target's location (the actual config file), and not from the
symlink.

This is with git version 1.8.5.3.

Please consider fixing this.

(I know about various workarounds, e.g. copying and adjusting "config"
or manually setting $GIT_WORK_TREE; more relevant discussion would be
at http://comments.gmane.org/gmane.comp.version-control.git/196019)


Thanks,
Daniel.

-- 
http://daniel.hahler.de/


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 255 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Bug: relative core.worktree is resolved from symlink and not its target
  2014-02-04 10:20 Bug: relative core.worktree is resolved from symlink and not its target Daniel Hahler
@ 2014-02-09  9:08 ` Duy Nguyen
  2014-02-17  9:36   ` Daniel Hahler
  0 siblings, 1 reply; 4+ messages in thread
From: Duy Nguyen @ 2014-02-09  9:08 UTC (permalink / raw)
  To: Daniel Hahler; +Cc: git

On Tue, Feb 04, 2014 at 11:20:39AM +0100, Daniel Hahler wrote:
> Hi,
> 
> 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.

$ pwd
/tmp/abc
$ ls -l .git/config 
lrwxrwxrwx 1 pclouds users 11 Feb  9 15:57 .git/config -> /tmp/config
$ cat /tmp/config 
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        worktree = ../../worktree
$ ls -l /tmp/worktree/
total 4
-rw-r--r-- 1 pclouds users 5 Feb  9 15:59 abc
$ ~/w/git/git ls-files -o
abc

Maybe it's something else. Could you produce a small test case?

> A fix would be to resolve any relative worktree setting based on the
> symlink target's location (the actual config file), and not from the
> symlink.
> 
> This is with git version 1.8.5.3.
--
Duy

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Bug: relative core.worktree is resolved from symlink and not its target
  2014-02-09  9:08 ` Duy Nguyen
@ 2014-02-17  9:36   ` Daniel Hahler
  2014-02-17 12:30     ` Duy Nguyen
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Hahler @ 2014-02-17  9:36 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 2616 bytes --]

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).

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.


Regards,
Daniel.

-- 
http://daniel.hahler.de/


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 255 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Bug: relative core.worktree is resolved from symlink and not its target
  2014-02-17  9:36   ` Daniel Hahler
@ 2014-02-17 12:30     ` Duy Nguyen
  0 siblings, 0 replies; 4+ messages in thread
From: Duy Nguyen @ 2014-02-17 12:30 UTC (permalink / raw)
  To: Daniel Hahler; +Cc: Git Mailing List

On Mon, Feb 17, 2014 at 4:36 PM, Daniel Hahler
<genml+git-2014@thequod.de> 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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-02-17 12:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-04 10:20 Bug: relative core.worktree is resolved from symlink and not its target Daniel Hahler
2014-02-09  9:08 ` Duy Nguyen
2014-02-17  9:36   ` Daniel Hahler
2014-02-17 12:30     ` Duy Nguyen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).