Subject: Re: [RFC] Submodules in GIT

From: Andy Parkins <[email-masked]>
Date: Tue, 28 Nov 2006 16:29:05 +0000

On Tuesday 2006 November 28 15:44, Shawn Pearce wrote:

> So HEAD in a submodule is the current content of that submodule.
> Therefore any update-index call on a submodule should load HEAD
> (totally ignoring whatever branch it refers to) into the supermodule
> index.

I was with you right up until here.

Why should a submodule do anything to the supermodule?  This is like saying, 
when I edit a working tree file, it should automatically call update-index.  
The supermodule index should only be updated in response to a manual 
update-index (or commit -a I suppose).

Worse, if you allow that to happen, the supermodule can commit a state that 
cannot be retrieved from the submodule's repository.  The ONLY thing a 
supermodule can record about a submodule is a commit.  Changing the index 
doesn't create a commit, so it can't change anything in the supermodule.

If you change the submodule index then that submodule is "dirty", this state 
has no parallel with normal git operation.  The nearest thing is that you've 
changed a file but not saved it.  Apart from showing the "dirty" state in the 
supermodule's git-status, I don't see that there is anything that the 
supermodule can do - it can't go around committing in a repository that it 
not itself.

IMO, it should always be possible to take a submodule and work on it in 
isolation - in an extreme case, by moving it out of the supermodule tree 
entirely.

In summary, from the supermodule's point of view:
 * A submodule with changed working directory is "dirty-wd"
 * A submodule with changed index is "dirty-idx" from the supermodule's
 * A submodule with changed HEAD (since the last supermodule commit) 
   is "changed but not updated" and can hence be "update-index"ed into the
   supermodule
 * A submodule with changed HEAD that has been added to the supermodule index
   is "updated but not checked in"
 * A submodule with changed HEAD (since the last supermodule update-index) is
   both "changed but not updated" _and_ "updated but not checked in", just 
   like any normal file.

What's needed then:
 * A way of telling git to treat a particular directory as a submodule instead
   of a directory
 * git-status gets knowledge of how to check for "dirty" submodules
 * git-commit-tree learns about how to store "submodule" object types in
   trees.  The submodule object type will be nothing more than the hash of the
   current HEAD commit.  (This might be my ignorance, perhaps it's just 
   update-index that needs to know this)

I don't know enough about the plumbing to know if my description above is 
using the right nomenclature - I'm sure someone will correct me.

In my head, it would look something like this:

$ mkdir supermodule; cd supermodule
$ git init-db
$ git clone proto://host/submodule.git
$ git add --submodule submodule
$ git update-index submodule
$ git commit -m "Added submodule to supermodule"
[ edit submodule ]
$ git status
submodule is dirty, the working directory has changed
[ update-index in submodule ]
$ git status
submodule is dirty, the index has changed
[ commit in submodule ]
$ git status
submodule is changed but not updated
$ git update-index submodule
$ git status
submodule is updated but not checked in
$ git commit -m "Record submodule change in supermodule"

Am I crazy?

Andy

-- 
Dr Andy Parkins, M Eng (hons), MIEE