Subject: Re: git-submodule getting submodules from the parent repository

From: Junio C Hamano <[email-masked]>
Date: Tue, 01 Apr 2008 17:35:03 -0700

"Avery Pennarun" <[email-masked]> writes:

> Instead of storing only the commitid of each submodule in the parent
> tree, store the current branch name as well.
> ...
> This way, cloning a project with submodules will work much like
> cloning the parent project; pushing and pulling the parent and the
> submodules will do as you expect.

That goes quite against the fundamental design of git submodules in that
the submodules are by themselves independent entities.  An often-cited
example is an appliance project, where superproject bundles a clone of
Linux kernel and a clone of busybox repositories as its submodules.

Each submodule is an independent project, and as such, must not know
anything about the containing superproject (iow, the superproject can know
what the submodules are doing, but submodules should not know they are
contained within a particular superproject).

If your superproject (i.e. the appliance product) uses two branches to
manage two product lines, named "v1" and "v2", these names are local to
the superproject.  It should not force the projects you borrow your
submodules from to have branches with corresponding name.

Also, the submodules and the superproject are meant to be loosely coupled.
A single branch in superproject (say "v1") may have many branches in a
submodule ("add frotz to v1 product", "improve nitfol in v1 product") that
can potentially be merged and bound to.

The work flow for updating a tree would look like:

 - People "git fetch" in superproject and in its submodules. They
   obviously prime their tree with "git clone" of superproject, and the
   submodules they are interested in, and a single fetch will update all
   the remote tracking branches, so it does not really matter which branch
   is checked out.  However, if you employ a central repository model to
   keep them, an invariant must hold: all the necessary commits in
   submodules must be _reachable_ from some branch in them.

 - When not working in a particular submodule, but using it as a component
   to build the superproject, it would be better to leave its HEAD
   detached to the version the superproject points at.  IOW, usually you
   won't have to be on any branch in submodules unless you are working in
   them.

 - Sometimes you need to work in a submodule; e.g. you would want to add
   'frotz' tool to your copy of busybox.  You chdir to the submodule
   directory, and develop as if there is no superproject.

   - Most likely, because the superproject and the submodules are meant to
     be tied loosely, the (detached) HEAD you see in the submodule
     together with the superproject may be _behind_ the tip of any
     branches in the submodule repository.  This is really up to the
     project's policy, but the superproject is meant to point at a commit
     from submodules that is proven to be robust, and it may even be the
     responsibility of people above you to decide when and to what commit
     to advance the commit the superproject points at, and developers are
     given a single "development" branch to work on.  The project policy
     might be "a new feature should be on a new topic branch forked at the
     commit the superproject points at, and let the project leader to know
     what the topic is about so that it can be merged to the integration
     branch".  Follow the project policy and check out the branch to work
     on.

   - Then work on adding that 'frotz' tool.  Make commits, test it in
     isolation and test with superproject.  Push it out as whichever
     remote branch the project policy asks you to.

 - If you are the person who decides which commit in a submodule should be
   pointed at by the tree of the superproject, then check out the
   superproject, and check out the submodule at that commit.  Update the
   gitlink for the submodule and make a commit in the superproject.  This
   step may happen at the same time as the previous step if you worked in
   the submodule to advance its development branch tip and if you are the
   person who decides which submodule commit to point at from the
   superproject.

 - At any step above, a new clone (or a previously cloned trees, updated
   with "git fetch" in appropriate places) will have all necessary
   objects.