Thread (2 messages) 2 messages, 2 authors, 2020-10-06

Re: git submodule init initialises submodules for which active=false has been defined

From: Philippe Blain <hidden>
Date: 2020-10-06 00:25:57

Hi Timur, 
Le 18 mars 2020 à 08:50, Timur Delahaye [off-list ref] a écrit :

Hello,

I am trying to prevent
git clone --recurse-submodules
from installing some of the submodules of the repo that are not necessary to most users.
OK. 
Here is what I did:
In my main-project

git submodule add --name one url1
git submodule add --name two url2

Then I edited .gitmodules as follows

[submodule "one"]
active = false
url = url1
[submodule "two"]
active = true
url = url2
Note: this could've been done with

    git config -f .gitmodules submodule.one.active false
    git config -f .gitmodules submodule.two.active true
commited and pushed.

From a fresh folder when I run
git clone --recurse-submodules main-repo-url
both "one" and "two" get installed
Yes. That's working as it should. If you take a look at the `git clone` documentation [1], 
you'll see that using '--recurse-submodules' without a pathspec will 
clone and initialize all submodules, and write '.' as the value of 'submodule.active'
(meaning, all submodules in the superproject are interesting).

If you do 

    git clone --recurse-submodules=two main-repo-url

then only "two" is cloned and initialized, but I think you're looking for something
more automatic than that.
Likewise if I do
git clone main-repo-url
git submodule init
both "one" and "two" are installed and appear in .git/config as well as .git/modules/
I would say that this is also working as it should. If you read 
the documentation  for `git submodule init` [2], 
you'll see that 

    "If no path is specified and submodule.active has been configured,
     submodules configured to be active will be initialized, 
     otherwise all submodules are initialized."

Note: nothing appears in .git/modules after `git submodule init`, 
but only after `git submodule update`, which is the logical next step
(or, you could do it in one step with `git submodule update --init)

I after your clone you instead do

   git submodule update --init two

then you'll get what you want (but again, I think you're looking for an automatic
way to do it that does not require spelling out "two" at or after the 'clone' step.)
Notice that if after your clone you do

    git config submodule.active two
    git submodule update --init

Then you get the same result (this is essentially what 
`git clone --recurse-submodules=two ...` does).
From reading https://git-scm.com/docs/gitsubmodules/2.25.0 my understanding was that both procedures should have installed only "two" and that I should have needed to do
git submodule init one
in order to force the local installation of the inactive module "one".

Either I misunderstood the manual or there is a bug with
git submodule init
I'd be interested to know which section of gitsubmodules(7) made you think that the 'active' 
setting would work in the way you're describing here, so it could be improved. 
(I have a feeling it's the sentence "Git only recurses into active submodules
 (see "ACTIVE SUBMODULES" section below).", but maybe there are other places).

Now, let's see if we can actually somehow achieve what you want to do.
If you read gitmodules(5) [3], you'll notice that 'submodule.<name>.active' is not
listed in the list of settings that can be found in a '.gitmodules' file ! So whatever
you were expecting Git to do with these settings is not happening. 
However, you'll also notice the setting `submodule.<name>.update`, which 
can be set to 'none' (see also [4]). And this, I think, is closer to what you want:

       git config -f .gitmodules submodule.one.update none
 
Try it out! with such a '.gitmodules', then 

   git clone --recurse-submodules

gives the following output:

$ git clone super-update/ clone-update --recurse-submodules 
Cloning into 'clone-update'...
done.
Submodule 'one' (/var/folders/lr/r6n2057j0dzd4gdb614fp0740000gp/T/submodule-active/one) registered for path 'one'
Submodule 'two' (/var/folders/lr/r6n2057j0dzd4gdb614fp0740000gp/T/submodule-active/two) registered for path 'two'
Skipping submodule 'one'
Cloning into '/private/var/folders/lr/r6n2057j0dzd4gdb614fp0740000gp/T/submodule-active/clone-update/two'...
done.
Submodule path 'two': checked out 'd02974612a8f64c1fff7e9de1d90d488606103d2'

and 'one' is neither cloned nor checked out. Similarly you can do

    git clone super-update clone-update
    cd clone-update
    git submodule update --init

and the last command outputs:

$ git submodule update --init
Submodule 'one' (/var/folders/lr/r6n2057j0dzd4gdb614fp0740000gp/T/submodule-active/one) registered for path 'one'
Submodule 'two' (/var/folders/lr/r6n2057j0dzd4gdb614fp0740000gp/T/submodule-active/two) registered for path 'two'
Skipping submodule 'one'
Cloning into '/private/var/folders/lr/r6n2057j0dzd4gdb614fp0740000gp/T/submodule-active/clone-update/two'...
done.
Submodule path 'two': checked out 'd02974612a8f64c1fff7e9de1d90d488606103d2'

and 'one' is neither cloned nor checked out. 
If this is not a bug but an error on my side, I would really appreciate some explanation about the active=false flag so I can achieve my purpose.
I hope the above helps! 
Note that I don't have a lot of experience with the 'submodule.<name>.update=none'
setting, (especially how it interacts with `git checkout --recurse-submodules`)
so I'd be really interested to know if the approach above works for you.


Cheers,

Philippe.

[1] https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---recurse-submodulesltpathspecgt
[2] https://git-scm.com/docs/git-submodule#Documentation/git-submodule.txt-init--ltpathgt82308203
[3] https://git-scm.com/docs/gitmodules
[4] https://git-scm.com/docs/git-submodule#Documentation/git-submodule.txt-none
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help