Re: RFC: Subprojects
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:42:16
Daniel Barkalow [off-list ref] writes:
So why not use the "bind" approach for the "index vs working tree" part, but write out "gitlink"-style tree objects?
I said "index vs working tree" as a mere example, and never said "gitlink" is easier (or at least as easy as "bind") for "tree object vs index" or "tree object vs working tree through index". In fact I suspect those parts also need to be changed fairly heavily, and to be honest, I am not very much looking forward to investigating the details.
In any case, I think it would be good to track where the subprojects are in some core state, and probably the right solution is to have special index entries for them, in addition to having their contents in the index.
Actually, the "special entry" was what I found out to be quite a pain, if you mean to have "linux-2.6/" in the index and have it used in some meaningful way. Further hacking and prototyping _might_ convince me otherwise, but I am not so optimistic at this moment.
I'm not seeing a clear way to get from commit objects with "bind" lines to an index with the appropriate things read and back otherwise.
Here again I am thinking aloud, remembering the earlier example
of an embedded linux project that ships with linux-2.6 and
gcc-4.0, along with its own README and Makefile at the toplevel
and src/ for its own sources. The tools at the tip of "pu"
should be able to let you do the following:
$ git cat-file commit $such_toplevel_commit
tree $tree
parent $parent
bind $primarysub /
bind $linuxsub linux-2.6/
bind $gccsub gcc-4.0/
author A U Thor [off-list ref] 1137392543 -0800
commmitter A U Thor [off-list ref] 1137392543 -0800
An example.
where $tree is the object name of the whole tree (no "gitlink"
object), $primarysub and $linuxsub are the object names of
commit objects for the primary subproject (which sits at the
rootlevel) and another subproject (which sits at linux-2.6/
subdirectory).
To make sure there is no misunderstanding:
* "git-ls-tree $tree" would show the object name of
$linuxsub^{tree} at path "linux-2.6/" because
"tree" line of a commit describes the whole tree,
including subprojects.
* "git-ls-tree $primarysub" would show README,
Makefile and src/ directories but not linux-2.6/ nor
gcc-4.0/.
* "git-ls-tree $linuxsub" would show COPYING, Makefile
etc., not linux-2.6/COPYING.
Reading such a commit is easy:
$ git-read-tree $tree ;# ;-)
But that is cheating. Constructing such an index can be done by:
$ git-read-tree $primarysub
$ git-read-tree --prefix=linux-2.6/ $linuxsub
$ git-read-tree --prefix=gcc-4.0/ $gccsub
When you have such an index, writing out various trees are:
$ git-write-tree ;# $tree
$ git-write-tree --prefix=linux-2.6/ ;# $linuxsub^{tree}
$ git-write-tree --prefix=gcc-4.0/ ;# $gccsub^{tree}
$ git-write-tree \
--bound=linux-2.6/ --bound=gcc-4.0/ ;# $primarysub^{tree}
The decision to use what --prefix and --bound and what tree(s)
to write out must come from somewhere, and as you say it would
be nice if we _could_ stick them in the index as "special
entries", but for the purpose of prototyping I am assuming I
keep that somewhere in $GIT_DIR/ (the "mtab" in the previous
message. Maybe "$GIT_DIR/bind" is a good name?).