Subject: Re: [RFC PATCH] clone: add clone.recursesubmodules config option

From: Jens Lehmann <[email-masked]>
Date: Wed, 04 Jun 2014 21:06:58 +0200

Am 04.06.2014 19:24, schrieb Junio C Hamano:
> Chris Packham <[email-masked]> writes:
> 
>> On 04/06/14 09:05, Junio C Hamano wrote:
>>>> Also, going --recursive when the user did not want is a lot more
>>>> expensive mistake to fix than not being --recursive when the user
>>>> wanted to.
>>>
>>> Having said all that, I do not mean to say that I am opposed to
>>> introduce some mechanism to let the users express their preference
>>> between recursive and non-recursive better, so that "git clone"
>>> without an explicit --recursive (or --no-recursive) can work to
>>> their taste.  A configuration in $HOME/.gitconfig might be a place
>>> to start, even though that has the downside of assuming that the
>>> given user would want to use the same settings for all his projects,
>>> which may not be the case in practice.
>>
>> And here's a quick proof of concept. Not sure about the config variable name
>> and it could probably do with a negative test as well.
> 
> I would be more worried about the semantics than the name, though;
> re-read the part you quoted with extra stress on "has the downside".
> 
> I think I heard the submodule folks (cc'ed) discuss an approach to
> allow various submodules to be marked with "tags" with a new type of
> entry in .gitmodules file in the superproject, and use these tags to
> signal "by default, a new clone will recurse into this submodule".
> 
> E.g. if projects standardized on "defaultClone" to mark such
> submodules, then $HOME/.gitconfig could say
> 
>     [clone]
>         recursesubmodules = defaultClone
> 
> Or the projects may mark platform specific submodules with tags,
> e.g. a .gitmodules in a typical superproject might say something
> like this:
> 
>     [submodule "posix"]
>     	path = ports/posix
>         tags = linux obsd fbsd osx
>     [submodule "windows"]
>         path = ports/windows
>         tags = win32
>     [submodule "doc"]
>     	path = documentation
>         tags = defaultClone
> 
> and then the user's $HOME/.gitconfig might say
> 
>     [clone]
>         recursesubmodules = defaultClone win32
> 
> to tell a "git clone" of such a superproject to clone the top-level,
> read its .gitmodules, and choose documentation/ and ports/windows
> submodules but not ports/posix submodule to be further cloned into
> the working tree of the superproject.
> 
> Of course, if this kind of project organization proves to be useful,
> we should try to standardize the set of tags early before people
> start coming up with random variations of the same thing, spelling
> the same concept in different ways only to be different, and if that
> happens, then we could even give a non-empty default value for the
> clone.recursesubmodules when $HOME/.gitconfig is missing one.

Yes, but maybe we can define how the user wants to set the global or
per-repo default (that is honored as long as upstream or local
config doesn't provide more specific settings, e.g. via tags) and
implement that for clone as a first step, even when we do not now
how e.g. the tags setting might look like in the end. I believe we
should have one or two switches telling Git "I want my submodules be
updated without having to use the 'git submodule' command". And
after that submodule specific overrides can kick in, e.g. when
"submodule.<name>.update" is set to "none" the submodule won't be
updated no matter how the default is.

We had two settings in mind, first "submodule.autoinit" (which would
automate the "git submodule --init" step and also control that a
new submodule is fetched into .git/modules; it'd be fetched there
soon as the fetch in the superproject sees a commit introducing it).
That would kick in on clone, fetch and pull, as the underlying fetch
honors it. And the "submodule.autoupdate" setting which will make
running "git submodule update" obsolete by updating all init'ed
submodules on each clone, checkout, merge, reset etc.. Together
they'd achieve for all relevant commands what Chris' proposed option
would only do for clone.

So what if clone would just do an "git submodule init" for now when
"submodule.autoinit" is set but "submodule.autoupdate" isn't (and as
soon as fetch learns to honor autoinit we could remove that one
again). And if both are set it'd do a "git submodule update --init
--recursive", just like it does when the --recurse-submodules option
is used. As soon as we also have recursive submodule update, we could
remove the latter from clone.

But maybe we are to close to the implementation side of things (where
fetch and checkout just like init and update are two separate things)
and a single "submodule.auto" setting would be what users really want?

Comments welcome.