git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [WIP PATCH 0/3] implement merge strategy for submodule links

From
Johan Herland <johan@herland.net>
Date
Jun 21, 2010, 22:35 UTC
Message-ID
<201006220035.31166.johan@herland.net>
In-Reply-To
<7vlja8if5r.fsf@alter.siamese.dyndns.org>
On Monday 21 June 2010, Junio C Hamano wrote:
Show 10 quoted lines
> Johan Herland <johan@herland.net> writes:
> > I still don't like this, as IMHO it's too subtle, and possibly
> > conflicts with explicitly tracking submodule branches (which, to me,
> > is a more important feature).
> 
> If you mean, by "explicitly tracking", to say "I don't care which commit
> from the submodule appears at this path, as long as it is at the tip of
> this branch", I still don't think it makes much sense, but what I
> outlined is not _incompatible_ with such a scheme.  In fact I think it
> would rather fit naturally as a sanity/safety measure.

I'll first try to explain where I'm coming from, to hopefully eliminate any confusion about my position:

IMHO, there should be 2 primary modes for submodules in Git:

A. Explicitly tracking submodule commits. This is the existing submodule behaviour. The superproject refers directly (in its tree) to a submodule commit. The .gitmodules file contains associated information (submodule.<name>.path, .url and .update).

B. Explicitly tracking submodule branches. An extra setting (submodule.<name>.branch) is added to the .gitmodules file, to determine which submodule branch to checkout. This setting overrides whatever submodule commit, if any, is stored in the superproject tree. There are two sub-modes for this mode:

B.1. There is no submodule entry at all in the superproject tree. This indicates that you are not at all interested in tracking the history of the submodule relative to the superproject. You are always interested in checking out the tip of submodule.<name>.branch in the submodule, even when digging into the superproject's history.

B.2. There is a submodule entry in the superproject tree. This "hybrid" approach indicates that although you primarily want to track a branch in the submodule (i.e. you mostly want the latest version of the submodule's branch), you still want a record of where your submodule has been pointing, in your superproject's history. Exactly when (or how often) the superproject's submodule entry should be updated is yet TBD. So is when to check out according to .branch, and when to use the recorded submodule commit. In the end, it'll probably be a policy decision for the projects that choose this approach.

Ok, that hopefully explains the basic idea of tracking submodule commits (A) vs. tracking submodule branches (B). Now, how would this apply to merging submodules?

In case of B, I'd argue that the submodule merging should _only_ look at the value of submodule.<name>.branch from the superproject's .gitmodules. If this setting is ambiguous (because of merge conflicts in .gitmodules), Git should not touch the submodule at all (until .gitmodules is resolved). Otherwise, Git's only task is to checkout whatever branch is specified by .gitmodules. If the commit that is checked out does not descend from all of the merge alternatives, a warning should be printed.

With that in mind, I enter this discussion because it might provide insight on how to solve the problem of merging submodules in scenario A.

In mode A there is no submodule.<name>.branch setting, and I would not like to add an additional setting (let's call it submodule.<name>.merge_branch for now) that is "weaker" than submodule.<name>.branch (meaning that it does not trigger the transition from mode A to mode B). There are two major reasons for this:

1. submodule.<name>.merge_branch would add semantics to the case of merging 
submodules that would be similar in spirit to what submodule.<name>.branch 
does (the "spirit" here is the special relationship to a submodule branch 
that we're establishing), but still the .merge_branch setting would be 
different in practice, by (a) only applying to the case of merging 
submodules (while .branch changes the semantics of almost all submodule 
operations), and (b) not even in the case of merging submodules would the 
options do the same thing. I fear the semantics of the .merge_branch option 
would be too complicated for an average user, and that its similarity to 
.branch would cause confusion.
2. What would happen if you enabled _both_ .merge_branch and .branch? In the 
case of merging submodules which setting will "win"? Even worse, if you set 
.merge_branch to "foo", and .branch to "bar", what will then happen?
Ok, so if I oppose adding .merge_branch, what do I propose instead?

Currently, not much, I'm afraid. But I have a gut feeling that the use case presented by Heiko and Jens is best solved EITHER by having no special branch relationships between the superproject and submodule (which AFAICS is what we currently agree on in this thread, and Heiko has already submitted a patch to this effect), OR by employing a conservative version of mode B.2 in which we use .branch to track a submodule branch, but still keep a close look at the recorded submodule commit, and, if necessary, maybe introduce some other options to tell Git when to use the recorded commit, and when to use the branch tip.

In other words, I think we should explore the .branch direction before we add complexity and potential confusion by prematurely adding another option that it somewhat similar to .branch in some contexts.

Show 5 quoted lines
> I presume that in your "explicitly tracked" world, if the user tries to
> commit at the superproject level with a submodule commit that is
> inconsistent with that "explicitly tracked" branch (e.g. the commit is
> not reachable from the tip of that branch), you would issue a warning of
> some sort, using that knowledge.
Yes.
> What I outlined uses the exact same
> knowledge of which branch in the submodule the superproject branch is
> tied to to reject irrelevant existing merges as resolution candidates.

True, but as I've argued above, I'm not sure that adding another setting (aka. .merge_branch) for this special/limited kind of branch tracking is worth it.

> Of course, this ".gitmodule in superproject can tell you which branch of
> submodule it follows" is optional; the user needs to take responsibility
> of picking the right one among I, E and G, of course, if the information
> does not exist or is not available.

Yes, of course. And this corresponds to what I've proposed for scenario A, when there is no branch-related setting specified for the submodule.

Hope this helps,
...Johan
-- 
Johan Herland, <johan@herland.net>
www.herland.net
Previous: Junio C HamanoNext: Junio C Hamano
Message 29 of 32 in “implement merge strategy for submodule links”
  1. 0/3 implement merge strategy for submodule linksHeiko Voigt, Jun 11, 2010
  2. 1/3 extend ref iteration for submodulesHeiko Voigt, Jun 11, 2010
  3. 2/3 add missing && to submodule-merge testcaseHeiko Voigt, Jun 11, 2010
  4. 3/3 implement automatic fast forward merge for submodulesHeiko Voigt, Jun 11, 2010
  5. Johan HerlandJun 12, 2010
  6. Heiko VoigtJun 12, 2010
  7. Johan HerlandJun 13, 2010
  8. Heiko VoigtJun 14, 2010
  9. Johan HerlandJun 14, 2010
  10. Jens LehmannJun 15, 2010
  11. Johan HerlandJun 16, 2010
  12. Jens LehmannJun 16, 2010
  13. Johan HerlandJun 16, 2010
  14. Junio C HamanoJun 16, 2010
  15. Johan HerlandJun 17, 2010
  16. Jens LehmannJun 17, 2010
  17. Johan HerlandJun 18, 2010
  18. Jens LehmannJun 18, 2010
  19. Heiko VoigtJun 19, 2010
  20. Jens LehmannJun 19, 2010
  21. Heiko VoigtJun 19, 2010
  22. Johan HerlandJun 19, 2010
  23. 3/3 implement automatic fast forward merge for submodulesHeiko Voigt, Jun 19, 2010
  24. Junio C HamanoJun 20, 2010
  25. Johan HerlandJun 20, 2010
  26. Junio C HamanoJun 21, 2010
  27. Johan HerlandJun 21, 2010
  28. Junio C HamanoJun 21, 2010
  29. Johan HerlandJun 21, 2010
  30. Junio C HamanoJun 22, 2010
  31. Johan HerlandJun 22, 2010
  32. Finn Arne GangstadJun 23, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.