I have just noticed that the order of these options in the config matters (latest wins), even though they seem slightly separate to me.
Going just by the documentation, I would expect "submodule.recurse = true" coupled with "fetch.recurseSubmodules = on-demand" of the other options to imply --recurse-submodules=on-demand; today, you can get the equivalent of "--recurse-submodules=true" depending on how you order these options in your config files.
This appears to also affect push.recurseSubmodules, since the code is similar.
The code, of course, just writes the same internal config variable when it sees either option; see builtin/fetch.c:git_fetch_config and builtin/push.c:git_push_config.
So I suppose I should ask: was this intentional? I didn't see much discussion on the mailing list thread for v2, v3 of the series that introduced submodule.recurse.
Would we consider it a breaking change (therefore a no-no?) to adjust option parsing for these 2 that the more-specific values can win? Or should we document somewhere (?) that the order matters?
-- D. Ben Knoble