Subject: Re: tracking submodules out of main directory.

From: Jens Lehmann <[email-masked]>
Date: Sat, 30 Jul 2011 16:16:11 +0200

Am 29.07.2011 11:39, schrieb henri GEIST:
> Le jeudi 28 juillet 2011 à 18:48 +0200, Jens Lehmann a écrit :
>> Am 28.07.2011 10:57, schrieb henri GEIST:
>>> In the current code it was not possible to add a gitlink to a repository
>>> outside of the main repository.
> 
> Of course that is why I have done the patch.
> 
>> Me thinks this is a *feature* this patch removes (as I understand it it was
>> a major design decision that everything /inside/ a directory is controlled
>> by git).
> 
> That is still the case.

No, as "everything /inside/ a directory" also means "nothing /outside/ that
directory" in this context.

> It is not a matter of disabling any control of git in its own
> repository.
> It is just a matter of adding inside the git repository a reference
> (dependency) to an other git repository.

... which you want to have *outside* of the containing repository! That will
then be registered in other git repositories too in your model, which gets
rid of the "one file/submodule, one repo" assumption we now have and will
introduce ambiguities which are *really* hard to handle.

>>> This pach :
>> <snip>
>>>   - Still forbids to add anything else.
>>
>> Why? If you let submodules live outside the tree I don't see any reason why
>> regular files shouldn't live there too (Disclaimer: I d not think that would
>> be a good idea either ;-).
> 
> there is regular file in the submodule repository but they are controled
> by the submodule itself. Then the main repository do not need to handle
> them.
> 
> Just like you I think that regular file should not be touche outside of
> the repository by git.

No, I think we should /either/ allow gitlinks *and* files to live outside of
the repository /or/ *none* of them, as they have a lot in common (and I'm
working on making them to behave as similar as possible). And in the use case
you describe here it is totally irrelevant if you dependency consists of a
directory tree in a submodule (= a bunch of files) or just a single file (say
a header containing project wide definitions).

> Because in this case it is not just a reference that is managed but the
> file itself. And this way there is a risk to overwrite some data not
> under revision control outside of the repository.

You have the same risk when a gitlink points outside, as a submodule is a
way of controlling a bunch of files through that reference. And the file
would be under version control in the repository where it is registered, no?

>> What you want looks like this:
>>
>> -+- lib1    #registered as submodule of project1 *and* project2 but not here
>>  +- project1            # submodule of the superproject
>>  |  +- ../lib1
>>  +- project2            # submodule of the superproject
>>     +- ../lib1
> 
> In fact no.
> What I want is to have this:
> 
> -+- lib1
>  +- project1
>  +- project2
> 
> With :
>  - lib1 not knowing anything about projects 1 & 2
>  - project1 not knowing anything about project2 and vice et versa
>  - project1 knowing that it need lib1 in version N.
>  - project2 knowing that it need lib1 in version M.

Right, I should have explained the "../lib1" entries better.

> I know that means a conflict in the required lib version but it is
> required by the independence of projects 1 & 2 which do not have to know
> what happen in the other one.
> 
> And in fact it is just what I want, it enable me if I decide to work on
> an optional "BigProject" depending on both project 1 & 2.
> 
> Then If lib1 is in version M:
>  - a git status in project2 will say nothing
>  - a git status in project1 will say
>    "modified:   ../lib1 (modified content)
>  - a git status in BigProject will say
>    "modified:   ../project1 (modified content)
> 
> Then I know that I need to update project1 to work with the last version
> M of lib1.

Maybe no update for project1 is needed, because M only contains a bugfix
which doesn't even need a recompilation of project1. But now you need to
add a commit to project1 nonetheless with a message like "Updated lib1
with a bugfix which is needed by project2" which makes your idea of
independent submodules break down.

>> You are opening a can of worms by having two different repos point to the same
>> submodule living in a third repo (which also happens to be their superproject
>> and must somehow ignore it). You'll have two SHA1s for a single submodule;
>> "git submodule foreach --recursive" will have interesting results too; and so
>> on. Not good.
> 
> As I just said before it is my purpose to do it like that.

I understood that, but what are you proposing to do to solve all the
problems your approach introduces? You can't just hand wave them away.

> Let say a concret exemple
> 
> 3 different teams work on libtiff, libpng, and libjpeg they are totally
> unrelated.
> 
> One more team is working on the "gimp". And they need those 3 libs in
> specific versions not necessarily there heads.
> 
> One other unrelated team is working on "gqview" and need the same libs
> in other specifics versions (Why should they know what te gimp team
> does)
> 
> Neither "gimp" and "gqview" project will contain directory with those
> libs inside. They just depend on them.
> 
> And the last team work on the gnome project which need the "gimp" and
> "gqview". It will be this team witch have to care about having both
> "gimp" and "gqview" sharing the same libs version>
> And has well the gnome project will not contain "gqview" and "gimp" in
> its own tree.
> It will also depend on them.

Cool, that is a real life example resembling what we have a my dayjob. But
a "gimp" and "gqview" project will only have dependencies like "use libpng
of version 1.2.3 or newer (because we need a feature/bugfix introduced
there)" and won't be tied to a special version of that library. This means
they need a dependency like "SHA1 or newer" instead of "exactly this SHA1".

> It is just the same with aptitude on debian.
> Each package know there dependency by themselves, does not contain there
> dependencies, and do not need a bigger superpackage to tell them what
> are there own dependencies.

And this is a very good point for the "version x.yy-z *or newer*" argument,
they are /never/ tied to the /exact/ x.yy-z version, as that would make the
dependencies pretty much unusable. They use a "newer than x.yy-z" scheme.

>> What about solving that with a "ln -s ../lib1" in "project1" and "project2"
>> (you seem to need that for your build environment) and adding the submodule
>> "lib1" to the superproject just like "project1" and "project2"?
>>
> 
> For my build environment I do not use simlinks.
> I use tu put :
> 
> #include "../lib1/lib1.h"
> in project1/project1.c
> 
> And even if I do not face this problem myself, simlinks do not work so
> well on Windows.

Agreed.

> And Still I realy want to have every project knowing there own
> dependency by themselves and not needing an external superproject to
> tell them what they need.

I want to have that too! I'm just convinced using a gitlink to achieve that
is wrong in so many ways. I'd rather prefer to express such dependencies in
something like a config file, and I believe they should not be as strict as
"I need exactly that version" but rather like "this version or newer (and by
the way: we of course only tested that specific version ;-)". These
dependencies could then be checked and displayed by git status.