# git-new-workdir submodules interact poorly with core.worktree

2 messages from 2014-09-12 to 2014-09-13. Participants: Edward Z. Yang, Jens Lehmann.
Thread: https://gitlist.dev/t/37544

## Edward Z. Yang, 2014-09-12 13:58

Subject: git-new-workdir submodules interact poorly with core.worktree
Message-ID: <1410527113-sup-9003@sabre>
URL: https://gitlist.dev/e/1410527113-sup-9003%40sabre

```
tl;dr You can't git-new-workdir checkouts which use core.worktree.  This
is unfortunate because 'git submodule init' uses core.worktree by
default, which means you can't recursively git-new-workdir without a
hack.

In the beginning, the Developer created the remote Git repository and
the submodule.

    mkdir -p remote/sub
    (cd remote/sub && git init && touch a && git add a && git commit -m "sub init")
    mkdir remote/top
    cd remote/top
    git init
    git submodule add ../sub
    git commit -m "top init"
    cd ../..

And the Developer said, "Let there be a local clone and submodule", and
lo, there was a local clone and submodule:

    git clone remote/top top
    (cd top && git submodule init && git submodule update)

the Developer blessed the working copy, and said "Be fruitful and
increase in number with git-new-workdir":

    git-new-workdir top worktop

Unfortunately, this workdir didn't have the submodules initialized.

    $ ls worktop/sub/
    $

Now, the Developer could have run:

    $ (cd worktop && git submodule init && git submodule update)

but the resulting submodule would not have been shared with the original
submodule, in the same way that git-new-workdir shared the Git metadata.

The Developer sought to create the submodule in its own likeness, but it
did not work:

    $ rmdir worktop/sub && git-new-workdir top/sub worktop/sub
    fatal: Could not chdir to '../../../sub': No such file or directory

What was the Developer's fall from grace?  A glance at the config of
the original and new submodule shed light on the matter:

    $ cat top/sub/.git
    gitdir: ../.git/modules/sub
    $ cat top/.git/modules/sub/config
    [core]
            repositoryformatversion = 0
            filemode = true
            bare = false
            logallrefupdates = true
            worktree = ../../../sub
    $ cat worktop/sub/.git/config
    [core]
            repositoryformatversion = 0
            filemode = true
            bare = false
            logallrefupdates = true
            worktree = ../../../sub

git-new-workdir sought to reuse the config of top/sub/.git, but this
configuration had core.worktree set.  For the original checkout,
this worked fine, since its location was .git/modules/sub; but for the
new workdir, this relative path was nonsense.

I do not think there is really a way to make this work with
core.worktree.  Our saving grace, however, is there is a hack that can
make this work: we just need to use the
pre-501770e1bb5d132ae4f79aa96715f07f6b84e1f6 style of cloning
submodules:

    git clone remote/top oktop
    git clone remote/sub oktop/sub
    (cd oktop && git submodule init && git submodule update)

Now recursive git-new-workdir will work.

What's the upshot?  I propose two new features:

1. A flag for git submodule update which reverts to the old behavior
of making a seperate .git directory rather than collecting them together
in the top-level .git/modules

2. Teach git-new-workdir to complain if core.worktree is set in the
source config, and how to recursively copy submodules.

What do peopl think?

Thanks,
Edward

```

## Jens Lehmann, 2014-09-13 11:25

Subject: Re: git-new-workdir submodules interact poorly with core.worktree
Message-ID: <541429AB.8030202@web.de>
URL: https://gitlist.dev/e/541429AB.8030202%40web.de
In-Reply-To: <1410527113-sup-9003@sabre>

```
Am 12.09.2014 um 15:58 schrieb Edward Z. Yang:
> tl;dr You can't git-new-workdir checkouts which use core.worktree.  This
> is unfortunate because 'git submodule init' uses core.worktree by
> default, which means you can't recursively git-new-workdir without a
> hack.
>
> In the beginning, the Developer created the remote Git repository and
> the submodule.
>
>      mkdir -p remote/sub
>      (cd remote/sub && git init && touch a && git add a && git commit -m "sub init")
>      mkdir remote/top
>      cd remote/top
>      git init
>      git submodule add ../sub
>      git commit -m "top init"
>      cd ../..
>
> And the Developer said, "Let there be a local clone and submodule", and
> lo, there was a local clone and submodule:
>
>      git clone remote/top top
>      (cd top && git submodule init && git submodule update)
>
> the Developer blessed the working copy, and said "Be fruitful and
> increase in number with git-new-workdir":
>
>      git-new-workdir top worktop
>
> Unfortunately, this workdir didn't have the submodules initialized.
>
>      $ ls worktop/sub/
>      $
>
> Now, the Developer could have run:
>
>      $ (cd worktop && git submodule init && git submodule update)
>
> but the resulting submodule would not have been shared with the original
> submodule, in the same way that git-new-workdir shared the Git metadata.
>
> The Developer sought to create the submodule in its own likeness, but it
> did not work:
>
>      $ rmdir worktop/sub && git-new-workdir top/sub worktop/sub
>      fatal: Could not chdir to '../../../sub': No such file or directory
>
> What was the Developer's fall from grace?  A glance at the config of
> the original and new submodule shed light on the matter:
>
>      $ cat top/sub/.git
>      gitdir: ../.git/modules/sub
>      $ cat top/.git/modules/sub/config
>      [core]
>              repositoryformatversion = 0
>              filemode = true
>              bare = false
>              logallrefupdates = true
>              worktree = ../../../sub
>      $ cat worktop/sub/.git/config
>      [core]
>              repositoryformatversion = 0
>              filemode = true
>              bare = false
>              logallrefupdates = true
>              worktree = ../../../sub
>
> git-new-workdir sought to reuse the config of top/sub/.git, but this
> configuration had core.worktree set.  For the original checkout,
> this worked fine, since its location was .git/modules/sub; but for the
> new workdir, this relative path was nonsense.
>
> I do not think there is really a way to make this work with
> core.worktree.  Our saving grace, however, is there is a hack that can
> make this work: we just need to use the
> pre-501770e1bb5d132ae4f79aa96715f07f6b84e1f6 style of cloning
> submodules:
>
>      git clone remote/top oktop
>      git clone remote/sub oktop/sub
>      (cd oktop && git submodule init && git submodule update)
>
> Now recursive git-new-workdir will work.

Thanks for the report and a nice summary.

> What's the upshot?  I propose two new features:
>
> 1. A flag for git submodule update which reverts to the old behavior
> of making a seperate .git directory rather than collecting them together
> in the top-level .git/modules

That would play bad with the upcoming recursive submodule update
(which needs .git/modules to safely remove a submodule work tree),
so I wouldn't want to do that step backwards.

> 2. Teach git-new-workdir to complain if core.worktree is set in the
> source config, and how to recursively copy submodules.

I'd prefer pursuing this approach.

```
