Subject: Re: [RFC] Submodules in GIT

From: sf <[email-masked]>
Date: Sat, 02 Dec 2006 00:34:31 +0100

Martin Waitz wrote:
> On Fri, Dec 01, 2006 at 06:33:12PM +0100, Stephan Feder wrote:
>> We are in agreement about two fundamental parts of the implementation 
>> and their meaning:
>>
>> 1. A submodule is stored as a commit id in a tree object.
>>
>> 2. Every object that is reachable from the submodule's commit are 
>> reachable from the supermodule's repository.
> 
> Correct.

Good. For me that is the main point. As I said before the user interface
is not so important because it can be changed anytime, but to change the
object database later is close to impossible.

...
> Let's see if I understand you correctly:
> 
> You don't want to create an additional .git directory for the submodule
> and just handle everything with one toplevel .git repository for the
> whole project.

Yes.

> Without the .git directory, you of course do not have refs/heads inside
> the submodule.

Correct..

> So this is a different user-interface approach to submodules when
> compared to my approach.  But the basis is the same and both could
> inter-operate.

Big YES.

> Now your submodule is no longer seen as an independent git repository
> and I think this would cause problems when you want to push/pull between
> the submodule and its upstream repository.

You can always pick a single commit or several commits out of a larger
repository and have a complete git repository.

And I already explained how to push and pull even from within superprojects.

> No technical problems, but UI-problems because now your submodule is
> handled completly different to a "normal" repository.

Yes and no. You can always have branches that are only concerned with
submodules' code, say, in refs/heads/submodules/<submodule>/.
"submodules" here is simply an example and has not deeper meaning. You
could call it foo or whatever you like. Or you could use
refs/heads/<submodule>/ if it suits you.

But if you mean the submodule as seen from the supermodule, then there
is a difference. Naturally, because the concept of submodules is new to git.

>>> Yes, but if it would have been integrated as a submodule it obviously
>>> would have been committed to the xdiff submodule inside the git
>>> repository.
>> No. The xdiff submodule would only exist as part of the git repository. 
> 
> But you could still call the "xdiff" part of the git repository a
> submodule.  And then changes to the xdiff directory result in a new
> submodule commit, even when there is no direct reference to it.
> So you'd still "commit to the xdiff submodule".

Let's make certain that we understand each other. I see a clear
distinction between the submodule code in a supermodule branch (commits
in the supermodule's tree and nothing else) and submodule branches which
are independent of the superproject. Supermodule branches and submodule
branches do not interact, only if I want them to.

> 
>> You could, f.e., access the xdiff commit in git HEAD as HEAD:xdiff// 
>> (again my proposed syntax). HEAD:xdiff//~2:xemit.c would give you the 
>> grandparent of xemit.c in the xdiff submodule.
> 
> git-cat-file commit HEAD:xdiff already works out of the box (even
> cat-file tree to get the submodule tree).  But up to now revision
> parsing follows the file name only once.
> 
> What about just separating things with "/"?
> 
> commit HEAD
> tree   HEAD/
> blob   HEAD/Makefile
> commit HEAD/xdiff
> tree   HEAD/xdiff/
> blob   HEAD/xdiff~2/xemit.c
> 
> this may add some confusion when used with hierarchical branches, but
> it's still unique:
> 
> 	refs/heads/master/xdiff/xemit.c
> 
> Just use as many path components until a matching reference is found,
> then start peeling.
> Or just use / between super and submodule:
> 
> 	refs/heads/master:xdiff/xemit.c
> 
> I think this is easier to read then
> 
> 	refs/heads/master:xdiff//:xemit.c

The double slashes is the only way I can think of that clearly indicates
that I do not mean the contents named by the path, but the commit that
you find there. Once you have named a commit in that way, you can
continue to apply other revision naming suffixes, paths, and so on.

Let's try. What does git cat-file -p
master:dir/sub//^^^:sub/dir/sub//^:dir/file mean?

Explanation: Take branch master and go to path dir/sub. There you will
find a commit. Take its grand-grandparent and go to path sub/dir/sub
(the first sub is a subproject as well but we do not care). There you
will, again, find a commit. Take its parent and go to path dir/file
which happens to be a blob the contents of which you want to cat.

In reality you will never see these kinds of complex paths. Have you
ever seen something like git cat-file -p
bd2c39f58f915af532b488c5bda753314f0db603~12^{commit}^2^5~8^2~308:README ?

>> If you mean the submodule repository created by init-module I 
>> understand. But why create this "helper repository at all"?
> 
> Because it helps "normal" git operations ;-)

Let's see. I still have to try.

Regards