Re: [RFC] remove/deprecate 'submodule init' and 'sync'
- From
W. Trevor King <wking@tremily.us>
- Date
- Dec 2, 2012, 19:09 UTC
- Message-ID
- <20121202190929.GG9401@odin.tremily.us>
- In-Reply-To
- <7vy5hhmcwp.fsf@alter.siamese.dyndns.org>
Before I get into the details, I'd like to point out that I actually understand the purpose of `submodule init` now ;). To avoid further confusion, my current one-line command summaries would be:
init: mark a submodule as active for future submodule operation
deinit: mark a submodule as inactive for future submodule operation
sync: update remote.<name>.origin in submodules to reflect changes
in .gitmodules or the superproject's remote URL.I don't think we disagree on that, we just don't agree on how to implement it.
Currently, Git uses submodule.<name>.url in the superproject's local configuration as a marker for submodule activation. This is not (as far as I know) discussed in the docs, which is why I initially missunderstood the purpose of `init` to be “setup the superproject's local configuration so we don't have to keep resolving the submodules URL relative to the superproject's upstream URL”. With the proposed `deinit` docs, this role for the submodule.<name>.url is mentioned, but not in a place where casual users will be able to easily connect it to the purpose of `init`.
I floated using submodule.<name>.update (with 'none' for inactive and anything else for active) as an alternative marker:
On Sat, Dec 01, 2012 at 01:16:43PM -0500, W. Trevor King wrote:
Show 17 quoted lines
> On Sat, Dec 01, 2012 at 07:04:05PM +0100, Jens Lehmann wrote: > > Am 01.12.2012 18:49, schrieb W. Trevor King: > > > I think removing `init` will cause some compatibility issues anyway, > > > so I was re-imaging how you do it. I don't think update='none' and > > > "don't populate my submodule" are distinct ideas, while a locally > > > configured url="somwhere" and "please populate my submodule" are (with > > > the blank-url case defaulting to the superproject itself). > > > > Why would we want to remove "init"? It still has to copy the "url" > > setting (and it would be a compatibility nightmare if we would change > > that, imagine different git versions used on the same work tree). > > In my init-less rewrite, it doesn't have to copy the url setting. > People using older versions of Git would need to run `init` using > their old version. Having the url defined in .git/config won't break > my init-less submodule commands, it just means that the value in > .gitmodules will be masked.
but that doesn't seem to be going over very well. Junio may have been weighing in obliquely with:
On Sat, Dec 01, 2012 at 06:00:06PM -0800, Junio C Hamano wrote:
Show 13 quoted lines
> Jens Lehmann <Jens.Lehmann@web.de> writes: > > [snip v1 deinit commit message] > > I fully agree with your analysis on the reason why the "url" element > is special and has to be copied to $GIT_DIR/config, but when you > deinit (or uninit) a submodule to say you are no longer interested > in it and do not want it populated in the context of the > superproject, I am not sure if removing only submodule.$name.url (so > that when you later decide to "init" it again, you will keep the > values for submodule.$name.update and other things from the previous > life) is the sane thing to do, or it is better to remove > submodule.$name.* altogether as if an earlier "init" has never > happened. Would it be worth analyzing the pros-and-cons here?
Let me take another stab at presenting my argument in favor of a different activity marker.
Proposal:
Add a new boolean option, submodule.<name>.active, to explicitly mark submodules as active (with “active” defined as “to be returned by module_list()”). Strip down `init` (and the --init part of `update --init`) to just setting this option to true. `deinit` only sets this option to false (but a `deinit --clean` could remove the whole submodule.<name> section).
With this in place, extracting URLs for submodule operations be similar to the extraction of other variables (.gitmodules defaults with superproject-local .git/config overrides). This also makes it easier to track maintenance updates in .gitmodules-defined URLs, because you aren't forced to bake overrides into your local .git/config
The upgrade path from earlier versions of Git is easy: if submodule.<name>.active is unset, use the presence of submodule.<name>.url to determine its initial value.
In the case where you check out an earlier superproject commit which is missing a particular submodule (or remove a submodule without deinit-ing), the presense of an active setting in .git/config should not cause an error, which they currently seem to:
On Sat, Dec 01, 2012 at 11:37:14AM -0500, W. Trevor King wrote:
Show 21 quoted lines
> On Sat, Dec 01, 2012 at 04:56:02PM +0100, Jens Lehmann wrote: > > Am 01.12.2012 00:52, schrieb Phil Hord: > > > If I never 'submodule init' a submodule, it does not get visited by > > > 'git submodule foreach', among others. I think some people use this > > > behavior explicitly. > > > > > > On the other hand, I've also notice that a submodule which I have > > > removed does not get de-inited later one. It causes my 'git submodule > > > foreach' to emit errors. :-( > > > > I'm currently hacking on "git submodule deinit" which removes the 'url' > > setting from git/config. This should do the trick for you, right? > > > > Just removing that submodule automagically would not work that well, as > > it would deinitialize a submodule when you switch to a branch where it > > isn't present and you'd have to reinitialize it when you come back. > > I think this is another case where we should be looping through > submodules based on the revision-specific .gitmodules content, and > querying the local config only to determine if the user wants to > update them (to drop into them with foreach, etc.).
Thoughts?
Trevor
-- This email may be signed or encrypted with GnuPG (http://www.gnupg.org). For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy