Assignee: RobertCollins
Created: 2005-10-15 by RobertCollins
Contributors: none yet
Status: BrainDump
Classifications: none yet
Queues: none yet
Implementation branch: none yet
Malone bugs:
Summary
There is desire to split trees into subsections
- because they contain parts that can vary (e.g. libraries that are also used elsewhere) and
- as a performance-enhancing technique. Can we do better than configs?
Rationale
Many projects such as Gnome and KDE use heavily nested trees to reduce code duplication, or to get customised copies of external libraries. Supporting such use cases is important to be a VCS that they can use project wide.
Further Details
There appear to be two useful forms of tree nesting - by value and by reference.
By Value
In CVS this is done by vendor imports, and in svn by the 'import' command. As we would like to track history across the nesting point, we will have a specific command to accomplish this. It could be a special behaviour on the import command, or it could be a new command such as 'join'.
By Reference
In CVS this is done by the module alias functionality, and in SVN by the 'svn:externals' facility. We will just use an explicit add:
bzr add path-to-nested-tree
to tell bzr to track the version of the nested tree. Importantly, bzr add and bzr add . will not trigger this, to avoid creating grief for folk that version their homedir.
Assumptions
Use Cases
Include a foreign library into my tree as a nested tree, so I can rearrange its directories outside of its former root. Then merge newer versions of the foreign library in, and vice verca.
Include a foreign library into my tree, as a bound branch against its master location, so that changes I make to it are shared between different users of that foreign library. Make a change in one tree that has that nested, pull in it in another tree to get a newer copy, and commit to record that it has been changed. Merge of the containing trees should do a merge of the nested trees.
new branch A, new child A/C, branch A B -> one empty tree with no child
branch A, added and committed child A/C, C has no commits, branch A B -> B has C but C has no commits
branch A, added and committed child A/C , branch A B -> B has C with commits
branch A, added and committed child A/C bound to ../../D, branch A B -> B has C with bind to ../../D.
branch DIR/A, added and committed child A/C bound to ../../D (=DIR/D), branch A ../B -> B has C with bind to ../../DIR/D.
- branch A, added and commited child A/C which is a checkout of ../../D - preserves checkout property and adjusts as per bound branch.
branch A, bound to regular branch ../E. Add regular branch C and commit -> E gets the inventory change to incorporate C; E also gets a copy of the working tree of C if the working tree of E is being updated/constructed.
branch A, bound to regular branch ../E. Add regular branch C. Run bzr give-me-a-better-child-finding-name(find-at?) C http://example.com/C and commit -> E gets the inventory change to incorporate C; E also gets a copy of the working tree of C if the working tree of E is being updated/constructed. The weave for .bzr-child-locations records the http://example.com/C location.
- branch A, bound to regular branch ../E. Add branch C bound to ../../D. On commit of A, E gets the inventory change to incorporate C;
added and committed child A/C, branch A B ->
how to construct the referenced tree ???????????????
copy history to subdir and keep there copy history to subdir and move to root .bzr on commit copy history to subdir and merge into root .bzr i.e. combine inventory, weave stores, revision stores.? copy history to subdir and use lockstep to reference remote location copy history to subdir, move to root .bzr and use lockstep to remote location? convert existing subdir into a bzr tree with its own history
by value:
- commit will:
- join inventories at the new revision,
incoporates all the childs inventories & weaves & revisions.
- join inventories at the new revision,
Implementation
This section should describe a plan of action (the "how") to implement the changes discussed. Could include subsections like:
UI Changes
Should cover changes required to the UI, or specific UI that is required to implement this
Code Changes
Code changes should include an overview of what needs to change, and in some cases even the specific details.
Schema Changes
Data Migration
Discussion
This section should house the larger issues that need discussing; you can sprinkle XXXs around the page if you want to keep the smaller open issues in context.
Unresolved Issues
Questions and Answers
dump
abentley: nested trees when you commit, the tree root is versioned as a new type, and the contents is the revision.
- its an inventory entry.
implications - the child trees position on the source tree for a merge is in the same relative path on the remote server.
robertc: nested trees are a config stored in .bzr and versioned. The config records the revision id of the tree root during commit. The default behaviour with merge etc will update this as per aarons proposal. However (as a possibility), the subordinate tree .bzr dirs are stored under this trees .bzr rather than in the child dir.
major options:
transparent management: By reference or by value or both ? CVS - both - modules & just take a copy SVN - both - external or take a copy/import .
aaron: library in two places. separate project.
bzr pull bzr merge what happens to subtrees ? are subtrees copied with the tree? how do I say 'this library does not change?' how to I convert dirs <-> subtrees?
- bzr the /lib/frob subtree of an older tree of mine.
how do I add a external tree if I commit in a subtree, is there a commit in the parent tree ? pull by default parent, merge default parent works bound branch default target works.
debian directory.
common debian skeleton merge that to each packages specific debian tree
to have a enxternal library that is customised in many user trees, and you can merge from the librarys parent to your specific user tree.
* nonversioned working tree property saying whether operations should propagate.
related... one inventory per directory, updating
revision history globally gives the sequence of 'this mainline'.
WHACKY IDEA FOR FUTURE DESIGN:
==============================
inventory entry: (parent id, parent rev id), (my id, my rev id), my name
if I change parent id or my name or my content object alters
then I get snapshotted -> record current pid, prid, mrid, name, content.
implications:
committing a file foo/bar/gam -> record a change to gam only at rev R
do not record top of tree change.
finding the tree from commit R:
V ids that have an R entry:
include their parent @ rev prid.
include the parents children at rev R - how do you define rev R for children not altered in R.
one way is to record the children in parent when parent changes - gives us children @ prid.
===================
dump
raw dump
09:36 < lifeless> ignore ui, mechanism, everything, just state what we want
09:36 < abentley> I want to be able to conveniently version several parts of a source tree in pieces, so that I can mix and match.
09:37 < lifeless> if you do an operation in a piece that contains other pieces, what should happen ?
09:38 < abentley> But I want to ensure that when that source tree is recreated, updated, etc, the results are always predictable.
09:38 < abentley> 'a piece that contains...': e.g. the top-level directory?
09:39 < lifeless> well
09:39 < lifeless> say you have a one file library which is a project of its own
09:39 < lifeless> and you have combined that with this other tree
09:40 < lifeless> if you do a log, or commit, or branch, of this larger tree, is that one file library logged, committed, or branched ?
09:40 < lifeless> and ...
09:40 < abentley> Yes, I would want commit, branch, pull (not sure about log) to be recursive.
09:40 < lifeless> does doing this stop this larger tree being its own entity, as its now dependent on the smaller library - have they become a composite.
09:41 < lifeless> or do you still want to be able to get the larger tree on its own without that library, from time to time ?
09:42 < abentley> err, if we extend to the bzrtools/pyarch case, I would want to be able to get bzrtools without it sometimes.
09:42 < lifeless> ok
09:42 < lifeless> so, we can imagine a command that adds in pyarch to bzrtools
09:43 < lifeless> 'bzr include <bzrtools path> <path>
09:43 < lifeless> and the next commit records this
09:44 < lifeless> lets say it records it in a control file, revision-id:[includes]
09:44 < lifeless> log and branch can be taugh to use that control file.
09:45 < lifeless> now, there are questions.
09:45 < lifeless> where does the data for the included branch go?
09:45 < lifeless> what do you do for an included branch where you only want one file from it
09:46 < lifeless> for the former case, I think in the root of the included branch
09:46 < lifeless> for the case of grabbing one file from another tree, thats tricky.
09:46 < lifeless> back in 20, breakfast time
09:46 < abentley> Cool
09:48 < lifeless> would log intersperse by date ?
09:48 < lifeless> (really gone now)
09:59 < abentley> lifeless: You should change your committer id on your laptop. Lifelesslap does not sound right *at all*.
10:19 < lifeless> back
10:19 < lifeless> ok, so thats when I forgot to rename bzr.conf :)
10:24 < abentley> left-hand, meet right-hand. :-)
10:26 < abentley> Log would intersperse by date, but subtree logs would be visually distinct from top-tree logs. Many log files only make sense in their
tree's context.
