Merge lp:~abentley/bzr/devnotes into lp:~bzr-core/bzr/devnotes

Proposed by Aaron Bentley
Status: Merged
Merged at revision: not available
Proposed branch: lp:~abentley/bzr/devnotes
Merge into: lp:~bzr-core/bzr/devnotes
Diff against target: 1369 lines
To merge this branch: bzr merge lp:~abentley/bzr/devnotes
Reviewer Review Type Date Requested Status
Robert Collins (community) Abstain
Review via email: mp+8766@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi all,

Here's my revised documentation for nested trees. In includes all three
documents: NestedTreesDesign from the wiki, Ian's proposed userdoc, and
the devnotes/nested-trees.txt from the most recent sprint.

I have updated them to provide a coherent view of nested trees,
harmonized with the design decisions made by Andrew Bennetts and me at
the sprint.

There's quite a lot of documentation to go over, so I may have missed
some inconsistencies. Please let me know if so.

Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkpctAMACgkQ0F+nu1YWqI2HMwCeMOEG/7vmjBkUfkgRKyRsXS78
nY4An3c4AprS3bb4mSFFsCMc30cA+ueD
=uzRm
-----END PGP SIGNATURE-----

Revision history for this message
Martin Pool (mbp) wrote :
Download full text (6.3 KiB)

This looks like a really nice clear description of the plan. I'm not sure if you're looking to merge it in as an indication it's definitely agreed this is what we'll do, or if you want to merge it as a work-in-progress for the spec.

I still have some doubts about whether recursing downwards is really what people want and/or is the safest strategy for introducing the feature. Maybe once we get this document merged in you can do a specific survey of users on that point. I realize it's been discussed before but the results seem to be mixed.

+seems likely that Bazaar will one day support them file copies, and when it

s/them//

134 +The branches associated with subtrees shall be called "subbranches".
135 +
136 +The branch for the top tree will be in a special format, whose last_revision
137 +file lists all the last_revision info for all of the branches associated with
138 +the nested tree. The .bzr directories of subtrees will have a "branch" that
139 +simply indicates that the top tree's branch should be used.
140 +
141 +In the top tree's last_revision file, the revision id and revno will be
142 +provided, indexed by the tree-reference file-id.
143 +
144 +The repository used by the top-tree's branch must be a shared repository, and
145 +will be used by the sub-branches.
146

I like this better than having separate whole branch control directories.

We'll probably have colocated branches in the same timeframe as this change so we should make sure they will mesh well.

Maybe add sub-branch to the glossary at the top?

But I think we need to back up here and clarify what these branches mean. (Unless you do that later.) I think what you want is:

When you commit in a subtree, it updates the sub-branch pointer. When you run log/etc/push/pull/merge in the subtree, it also uses this pointer. When you commit in the containing tree, it writes the current values of these sub-branch pointers into the inventory for the enclosing tree.

If you're looking at an already-committed version of the containing tree, it'll find the subtrees by looking in the containing tree's inventory.

This seems to imply that the sub-branches are almost just working tree data -- if you're not interested in commits that haven't been wrapped up in a containing tree commit yet, you don't need to see them.

So would it be enough then to just have plain trees with branches in there?

Presumably this adds a constraint on repositories (or clarifies a constraint) that a repository that contains a nested tree revision should hold all the data needed for the subtrees.

202 +Implementation strategies
203 +*************************
204 +

It's not clear here if you're going to describe several alternative implementation strategies...

230 +The obvious way to prevent slowness when there are no subtrees is to provide a
231 +fast way of determining whether there are subtrees. This could be provided by
232 +additional on-disk indices, or potentially by providing a flag indicating
233 +whether there are subtrees. Such a flag could be updated by Tree.iter_entries,
234 +to avoid re-running Tree.iter_entries. A parallel flag for iter_changes is
235 +also conceivable, but would be more com...

Read more...

Revision history for this message
Aaron Bentley (abentley) wrote :
Download full text (8.0 KiB)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Martin Pool wrote:
> This looks like a really nice clear description of the plan. I'm not sure if you're looking to merge it in as an indication it's definitely agreed this is what we'll do,

Yes.

> I still have some doubts about whether recursing downwards is really what people want and/or is the safest strategy for introducing the feature. Maybe once we get this document merged in you can do a specific survey of users on that point. I realize it's been discussed before but the results seem to be mixed.

You have asked me to reconsider it before. The last time, I took your
advice and asked Andrew Bennets' opinion, doing my best to fairly lay
out the pros and cons of each strategy, and he chose downwards
recursion. Please accept that.

I recognize that you have doubts, but I have doubts about doing it the
other way. We've reviewed it multiple times, and each time the outcome
was downwards recursion.

> +seems likely that Bazaar will one day support them file copies, and when it
>
> s/them//
>

Fixed.

> 134 +The branches associated with subtrees shall be called "subbranches".
> 135 +
> 136 +The branch for the top tree will be in a special format, whose last_revision
> 137 +file lists all the last_revision info for all of the branches associated with
> 138 +the nested tree. The .bzr directories of subtrees will have a "branch" that
> 139 +simply indicates that the top tree's branch should be used.
> 140 +
> 141 +In the top tree's last_revision file, the revision id and revno will be
> 142 +provided, indexed by the tree-reference file-id.
> 143 +
> 144 +The repository used by the top-tree's branch must be a shared repository, and
> 145 +will be used by the sub-branches.
> 146
>
> I like this better than having separate whole branch control directories.
>
> We'll probably have colocated branches in the same timeframe as this change so we should make sure they will mesh well.
>
> Maybe add sub-branch to the glossary at the top?

Done

>
> But I think we need to back up here and clarify what these branches mean. (Unless you do that later.) I think what you want is:
>
> When you commit in a subtree, it updates the sub-branch pointer. When you run log/etc/push/pull/merge in the subtree, it also uses this pointer. When you commit in the containing tree, it writes the current values of these sub-branch pointers into the inventory for the enclosing tree.
>
> If you're looking at an already-committed version of the containing tree, it'll find the subtrees by looking in the containing tree's inventory.

Agreed.

> This seems to imply that the sub-branches are almost just working tree data -- if you're not interested in commits that haven't been wrapped up in a containing tree commit yet, you don't need to see them.
>
> So would it be enough then to just have plain trees with branches in there?

If you mean trees whose branches are in the same .bzr, that is problematic.

- - We want a guarantee that all the branches share a single repository
- - It doesn't provide synchonized control of push/pull/submit locations
- - Bzr will create or delete the branches at will, trashing any user
custo...

Read more...

lp:~abentley/bzr/devnotes updated
35. By Aaron Bentley

Updates from review

Revision history for this message
Robert Collins (lifeless) :
review: Abstain
Revision history for this message
Martin Pool (mbp) wrote :

I'll merge this into devnotes; it may need some more thought about foreign branch support but it's worth checkpointing this.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nested-trees.txt'
2--- nested-trees.txt 2009-05-29 15:50:06 +0000
3+++ nested-trees.txt 2009-08-25 03:35:20 +0000
4@@ -2,43 +2,121 @@
5 Nested Trees
6 ************
7
8+.. sectnum::
9+
10+.. contents::
11+
12 Principles
13 **********
14
15 - Never store a location in versioned data.
16
17 - Implementation of nested trees shall not make operations observably slower
18- for those not using nested trees. (Using nested trees will impact performance
19- in the initial implementation, but the design will allow a performant
20- implementation.)
21+ for those not using nested trees. (Using nested trees will impact
22+ performance in the initial implementation, but the design will allow a
23+ performant implementation.)
24
25 - A repository that holds a revision R should be able to reconstruct the
26 whole contents of that revision, including any nested trees. Corolary:
27 if I fetch that revision, even into a branch that has no working tree, it
28 should bring across any referenced revisions.
29
30-- A project with zero nested trees must pay zero performance cost when
31- using a format supporting them.
32-
33-Design
34-******
35-
36-(See also <http://bazaar-vcs.org/NestedTreesDesign>)
37-
38-Inventory entries of type 'tree reference' have a file-id and a revision-id.
39-
40-In the working tree, subtrees are represented as a subdirectory. The top
41-containing tree's branch will be in a format that contains:
42-
43- - the last-revision pointers for all the nested branches indexed by the file-id
44- of their tree reference.
45- - the subbranches will use the same repository as the top tree. This
46- repository may be at the top tree, or a shared repository used by the top
47- tree.
48-
49-On disk, the subtrees will simply indicate that their data is stored in a top
50-tree. The top tree for a subtree is located by walking parent dirs until a top
51-tree is found.
52+Core Concepts
53+*************
54+
55+**Subtree** A tree which is inside another tree, which bzr has been asked to
56+treat as part of the outer tree.
57+
58+**Subbranch** The branch associated with a subtree.
59+
60+**Containing tree** A tree which has another tree inside it
61+
62+**Tree reference** A directory in a containing tree which contains a subtree.
63+
64+**Composite tree** A tree which behaves as a single tree, but is actually made
65+up of several trees.
66+
67+
68+Basic design approach
69+*********************
70+(see "Design decisions" for extended rationale)
71+By default, commands in containing trees should behave as though the subtrees
72+were plain directories. By default, commands in subtrees should not affect the
73+containing trees.
74+
75+Downwards recursion
76+~~~~~~~~~~~~~~~~~~~
77+One of the objectives of nested trees is to provide ways of reproducing
78+historical combinations of different codebases. The dependency chain points
79+downwards, such that trees are affected by the revision of their subtrees, but
80+subtrees are oblivious to their containing trees. Just as bazaar doesn't
81+entice people to commit inconsistent trees, it should not entice people to
82+commit inconsistent combinations of containing tree and subtree. Therefore,
83+commit should recurse downwards by default.
84+
85+Status and diff should reflect what will happen when commit is used, so they
86+should also recurse downward by default. Add almost does this already. With
87+status, diff, commit and add recursing downwards, it would be confusing to
88+users if other operations did not. Therefore, all operations should recurse
89+downwards by default.
90+
91+No upwards recursion by default
92+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
93+One of the reasons for using nested trees is to gain performance by only
94+committing in a subtree. Therefore, operations should not recurse upwards by
95+default. However, some users do want to have upwards recursion, so it should
96+be provided as an option.
97+
98+Modelling nested trees as a composite tree.
99+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100+The idea that a set of nested trees behaves like a single, larger tree seems
101+relatively easy to grasp. Both for users and for developers, it provides a
102+clear expectation for the behaviour of nested trees. There are no obvious
103+drawbacks in terms of code clarity or performance. Therefore, it seems like a
104+good model to start with.
105+
106+There are cases where users place multiple copies of a source tree inside
107+another tree, and treating a set of nested trees like a single large tree is in
108+conflict with that. It is essentially the same as supporting file copies, and
109+file copies themselves are a big and complicated feature to implement. It
110+seems likely that Bazaar will one day support file copies, and when it does,
111+this conflict will disappear. Implementing limited support for copies via
112+nesting would have similar complexity to implementing general support for file
113+copies, but would have fewer fruits. It would lead to complication when true
114+support for file copies is implemented. It does not seem appropriate for
115+initial nested-tree support. On the other hand, it could be implemented later;
116+none of the data model changes are in conflict with that.
117+
118+Using root file-ids for tree-references
119+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120+The idea that tree-reference file-ids are the same as the file-ids of the
121+corresponding root directories has a nice symmetry. It is one way of ensuring
122+that "bzr split" is deterministic, and "bzr join" is deterministic. When
123+performing operations involving a tree and a split version of that tree, using
124+the same file-id makes it easy to ensure that operations such as moves and
125+renames are applied appropriately to the tree-reference. Providing mechanisms
126+whereby a tree-reference can be treated as it would if it had its old file-id
127+encroaches on the territory of path tokens or file-id aliases. Having "split"
128+cause file-id changes means that in comparing these revisions, it would be seen
129+as a deleting a directory and creating a new tree-reference with the same name.
130+Handling this correctly in operations such as merge and revert would be more
131+complicated than if it were treated as a kind change, especially when
132+unversioned files are present in the subtree.
133+
134+Sub-branches
135+~~~~~~~~~~~~
136+The branches associated with subtrees shall be called "subbranches".
137+
138+The branch for the top tree will be in a special format, whose last_revision
139+file lists all the last_revision info for all of the branches associated with
140+the nested tree. The .bzr directories of subtrees will have a "branch" that
141+simply indicates that the top tree's branch should be used.
142+
143+In the top tree's last_revision file, the revision id and revno will be
144+provided, indexed by the tree-reference file-id.
145+
146+The repository used by the top-tree's branch must be a shared repository, and
147+will be used by the sub-branches.
148
149 Only the top branch will have a branch.conf. When an operation on a subbranch
150 would normally use values from branch.conf it will look them up in the top
151@@ -46,25 +124,871 @@
152 push" in a subtree will push just that subbranch to the corresponding subbranch
153 in the configured push location of the top branch.
154
155-Process
156-*******
157-
158-How do we best manage the risk associated with this complex feature?
159-
160-Is it by getting something out there and planning/expecting a few
161-iterations to smooth out issues? Is it by taking more time before
162-coding and landing patches to discuss the design? Or a mix of these?
163-
164-We need to be careful. On the one hand, we don't want to put user
165-data at risk and that's possible if the core data model (not caches)
166-is flawed. On the other, we don't want to get bogged down worrying
167-about obscure edge cases now at the expense of solving the common
168-cases well. This feature will be a classic case of 90% of users
169-only needing 10% of the capability IMNSHO. (igc)
170-
171-
172-Undecided questions
173-*******************
174+Rationale
175+.........
176+If the branches were not local, the local subtrees might not be committable,
177+and commits to the remote branch would make the local subtree out of date.
178+They should not be in a separate location from the containing branch, because
179+they might share history with the tree-reference's branch. However, those
180+local branches should not be at the same location as their tree, because the
181+tree might be deleted or moved. Indeed, they should not be anywhere within a
182+working tree.
183+
184+subtree branches should not be above or beside their containing branch, because
185+it could cause terrible confusion if subtrees from two different trees were
186+updating the same branches with every push, pull, commit and uncommit.
187+
188+Subtree branches could be plain branches stored somewhere in the top tree's
189+branch, but then a lookup mechanism would be needed to translate from file_id
190+to location, and performance with large numbers of subbranches would be poor.
191+
192+Pull and non-initial push
193+~~~~~~~~~~~~~~~~~~~~~~~~~
194+When a pull involves updates to tree references, pull will always pull into the
195+reference branch. For all new revisions in the upper branch, it will determine
196+the revision values of tree references, and fetch them into the repository.
197+
198+When new tree references are encountered, pull should create a corresponding
199+subbranch in the top branch.
200+
201+Pulls will update the subtrees whose tree-references change, including creating
202+trees for new sub-branches.
203+
204+Implementation strategies
205+*************************
206+
207+Start from the top
208+~~~~~~~~~~~~~~~~~~
209+In the initial implementation, recursion into subtrees should be implemented at
210+the highest level possible. This will make experimentation easier, reduce the
211+chance for regressions in core code, and reduce the number of public API
212+changes. This will entail some redundant post-operation determination of
213+whether subtrees are present. Speed of operations involving subtrees is not a
214+major concern, but operations that do not use subtrees must not be observably
215+slower.
216+
217+Aaron Bentley believes that recursion at the top level is also easier to
218+understand and debug, but Robert Collins and Vincent Ladeuil disagree.
219+
220+As time goes on and the design is proven, operations can be rewritten as more
221+intrusive changes, in order to provide better performance or better handling of
222+edge cases. It may make sense to implement them on NestedTrees, so that they
223+can take advantage of its subtree caching.
224+
225+However, some low-level operations would be dubious to implement as recursive.
226+For example, a recursive Tree.id2path might open several subtrees in order to
227+determine a single path. It would be better to support a batch operation in
228+NestedTrees.
229+
230+Fast subtree detection
231+~~~~~~~~~~~~~~~~~~~~~~
232+The obvious way to prevent slowness when there are no subtrees is to provide a
233+fast way of determining whether there are subtrees. This could be provided by
234+additional on-disk indices, or potentially by providing a flag indicating
235+whether there are subtrees. Such a flag could be updated by Tree.iter_entries,
236+to avoid re-running Tree.iter_entries. A parallel flag for iter_changes is
237+also conceivable, but would be more complicated, since iter_changes is relative
238+to another Tree. Further, during ``iter_changes`` it is possible to have
239+subtrees that were not encountered because they were unchanged between the
240+trees (as ``iter_changes`` does not always walk the entire tree).
241+
242+Composite Locking
243+~~~~~~~~~~~~~~~~~
244+Locking a NestedTrees should lock all subtrees, to reduce the potential for new
245+failure modes. This suggests the need for an on-disk index of subtrees.
246+
247+CompositeTree
248+~~~~~~~~~~~~~
249+For some operations such as diff, status and export, knowing which directories
250+are tree references is not essential. They can be satisfied by a Tree
251+implementation that papers over tree-references, making the set of nested trees
252+look like a single big tree with directories instead of tree-references. This
253+implementation strategy has a limited scope, and probably a limited shelf life,
254+but provides a fast way of getting coverage of several important commands.
255+
256+Scope
257+*****
258+Ultimately, all commands should support nested trees. Initial work is focused
259+on:
260+
261+- checkout
262+- branch
263+- push
264+- pull
265+- merge
266+- revert
267+- mv
268+- status
269+- diff
270+- commit
271+- export
272+
273+
274+Data storage
275+************
276+
277+Trees
278+~~~~~
279+The root-ids of trees must be unique, so that the same file-id can be used in
280+both the containing tree and the subtree, to simplify access within trees.
281+Tree references are an inventory type that is distinct from a directory, and
282+has a revision-id associated with it.
283+All modern working trees support tree references. Indices may be provided to
284+ensure fast access to the list of subtrees.
285+
286+Because of the need to use branches for recursion, it would be desirable to
287+associate RevisionTrees with branches. The alternative is for many operations
288+to accept Tree + Branch as input, and return Tree, Branch pairs.
289+
290+Branches
291+~~~~~~~~
292+A new branch format, "subbranches", is introduced which provides multiple
293+sub-branches, with their data referenced by file-id. A new branch refrerence
294+format, "subbranch-reference", is introduced which refers to sub-branches in a
295+"subbranches" branch.
296+
297+Repositories
298+~~~~~~~~~~~~
299+Some repository formats have 'subtree' variants, e.g. pack-0.92-subtree,
300+development-subtree. These are hidden, experimental formats that support
301+storing tree-references in their inventory formats. The most recent format
302+which supports subtrees is RepositoryFormatKnitPack3.
303+
304+Repository indexing might be extended to provide fast access to
305+tree-references.
306+
307+Commands
308+********
309+
310+The following new commands are introduced:
311+
312+``split`` Convert a single working tree into two trees, one inside the other.
313+
314+``join --nested`` Cause an inner tree to be treated as a subtree. The outer
315+tree's branch must be in the new "subbranches" format. The inner tree's branch
316+will be cloned into the "subbranches" branch, and the local branch will be
317+replaced with a "subbranch-reference". Finally, a tree-reference will be
318+added to the containing tree.
319+
320+API Changes
321+***********
322+
323+Introduce NestedTrees
324+~~~~~~~~~~~~~~~~~~~~~
325+New class to provide services for sets of nested trees, including coordinating
326+locking, caching Tree instances, and mapping file-ids and paths to the
327+appropriate Tree and Branch. Includes::
328+
329+ NestedTrees.lock_read
330+
331+ NestedTrees.lock_write
332+
333+ NestedTrees.unlock
334+
335+ NestedTrees.paths_info(self, paths)
336+ - return a list of tuples of Tree, relpaths, where relpaths is a list of
337+ relative paths, and Tree is the subtree that contains them.
338+
339+ NestedTrees.get_tree_and_treepath
340+ - return the tree and relative path within that tree of a file-id
341+
342+ NestedTrees.apply_inventory_delta
343+ - splits an inventory delta into the affected subtrees and applies it to them
344+ all
345+
346+ NestedTrees.iter_changes
347+ - provide iter_changes over a set of nested subtrees. Emits tree-references
348+ in preference to tree roots.
349+
350+
351+Introduce NestedTreeTransform
352+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
353+New class to permit smooth recursion of TreeTransform operations like merge and
354+revert even when the subtree boundaries differ. API essentially the same as
355+TreeTransform, except that tree-references can have children, as directories
356+do.
357+
358+Introduce CompositeTree
359+~~~~~~~~~~~~~~~~~~~~~~~
360+New class to provide easy transition of superficial commands like diff, status,
361+export. API is a subset of Tree API. Additional methods::
362+
363+ CompositeTree.maybe_composite
364+
365+ - return a CompositeTree if the input tree has subtrees, otherwise return the
366+ input Tree. This restricts the scope of any regressions to Trees that
367+ are actually using the features.
368+
369+New Tree methods
370+~~~~~~~~~~~~~~~~
371+
372+ get_nested_tree_and_branch(file_id, branch)
373+
374+ - Return a Tree and Branch for the tree-reference with the specified file_id
375+
376+Tree changes
377+~~~~~~~~~~~~
378+
379+ WorkingTree will cache the list of tree-references, to accelerate
380+ WorkingTree.iter_references. This may be an in-memory cache, or it may
381+ require a new format.
382+
383+ WorkingTree.pull recurses downwards by default. Subtrees are pulled from the
384+ reference location of the specified branch.
385+
386+ MutableTree.commit recurses downwards by default.
387+
388+ WorkingTree.revert recurses downwards by default.
389+
390+ Merger recurses downwards by default. This is not equivalent to running merge
391+ in each of the subtrees-- it uses the tree-reference revision-id to determine
392+ which revision to merge into each subtree, recursively. Merger should not
393+ care whether subtree boundaries have changed. Like WorkingTree.pull, it
394+ fetches from the reference location of the branch associated with the tree.
395+
396+New Branch methods
397+~~~~~~~~~~~~~~~~~~
398+ get_subbranch
399+
400+ - Return branch for tree reference
401+
402+Branch changes
403+~~~~~~~~~~~~~~
404+
405+ pull recurses into reference branches, and pulls *from* the source's reference
406+ branches.
407+
408+Repository changes
409+~~~~~~~~~~~~~~~~~~
410+
411+ fetch provides a list of tree-reference revision ids/file-id pairs for the
412+ revisions that were fetched. Fetch automatically fetches all revisions
413+ associted with tree-references that were fetched.
414+
415+Use Cases
416+*********
417+
418+Case 1
419+~~~~~~
420+Barry works on a project with three libraries. He wants to keep up to date
421+with the tip of those libraries, but he doesn't want them to be part of his
422+source tree.
423+
424+Example commands::
425+
426+ Set up the tree:
427+ $ bzr branch --nested http://library1 project
428+ $ bzr branch --nested http://library2 project
429+ $ bzr branch --nested http://library3 project
430+ $ bzr commit project -m "Added three libraries"
431+
432+ Update a library to tip:
433+ $ bzr pull -d project/library1 http://library1
434+
435+Case 2
436+~~~~~~
437+Now, Barry wants to add a fourth library.
438+
439+Example commands::
440+
441+ $ bzr branch --nested http://library4 project
442+
443+Case 3
444+~~~~~~
445+Barry wants to publish his project.
446+
447+Example commands::
448+
449+ $ bzr push -d project bzr+ssh://project/trunk
450+
451+Case 4
452+~~~~~~
453+Barry decides to make part of his project into another library
454+
455+Example commands::
456+
457+ $ bzr split --nested project/newlibrary
458+
459+Case 5
460+~~~~~~
461+Curtis wants to hack on Barry's project
462+
463+Example commands::
464+
465+ $ bzr branch http://project/trunk
466+
467+Case 6
468+~~~~~~
469+Barry wants to drop one of the libraries he was using
470+
471+Example commands::
472+
473+ $ rm project/library1
474+ $ bzr commit project -m "Removed library1"
475+
476+Case 7
477+~~~~~~
478+Curtis has made changes to one of the libraries. Barry wants to merge Curtis'
479+changes into his copy.
480+
481+Example commands::
482+
483+ $ bzr merge -d project http://curtis.org/trunk#library2
484+
485+ Or alternatively:
486+ $ bzr merge -d project/library2 http://curtis.org/trunk#library2
487+
488+Case 8
489+~~~~~~
490+Curtis has made changes to Barry's main project. Barry wants to merge Curtis'
491+changes into his copy.
492+
493+Example commands::
494+
495+ $ bzr merge -d project http://curtis.org/trunk
496+
497+
498+Case 9
499+~~~~~~
500+Barry makes changes in his project and in a library, and he runs status
501+
502+Example commands::
503+
504+ $ echo bar > project/foo
505+ $ echo qux > project/library2/baz
506+ $ bzr status project
507+ M foo
508+ M library2/baz
509+
510+Case 10
511+~~~~~~~
512+Barry wants to upgrade the bazaar format of his project
513+
514+Example commands::
515+
516+ $ bzr upgrade project
517+
518+Case 11
519+~~~~~~~
520+Curtis wants to apply Barry's latest changes.
521+
522+Example commands::
523+
524+ $ bzr merge -d project http://project/trunk
525+
526+Case 12
527+~~~~~~~
528+Danilo wants to start a project with two libraries using nested trees from
529+scratch.
530+
531+Example commands::
532+
533+ $ bzr init project
534+ $ bzr branch --nested http://library4 project
535+ $ bzr branch --nested http://library5 project
536+ $ bzr commit project -m "Created new project."
537+
538+Case 13
539+~~~~~~~
540+Edwin has a project that doesn't use nested trees and he wants to start using
541+nested trees.
542+
543+Example commands::
544+ $ bzr split --nested project/subdir
545+
546+Case 14
547+~~~~~~~
548+Françis has a project with nested trees where the containing tree uses one
549+Bazaar format and the subtree uses a different Bazaar format.
550+
551+Not supported.
552+
553+Case 15
554+~~~~~~~
555+Barry commits some changes to a library and to the main project, and then
556+discovers the changes are not appropriate. He has not yet pushed his changes
557+anywhere.
558+
559+Example commands::
560+
561+ $ bzr merge -d project http://library2
562+ $ bzr commit project -m "Updated library2"
563+ $ bzr uncommit project --force
564+
565+Case 16
566+~~~~~~~
567+Barry commits some changes to a library and to the main project, publishes his
568+branch, and then discovers the changes are not appropriate.
569+
570+Example commands::
571+
572+ $ bzr merge -d project http://library2
573+ $ bzr commit project -m "Updated library2"
574+ $ bzr push -d project
575+ $ bzr revert project
576+ $ bzr commit project -m "Reverted inappropriate changes."
577+ $ bzr push -d project
578+
579+Case 17
580+~~~~~~~
581+Gary is writing a project. Henninge wants to split a library out of it.
582+
583+Example commands::
584+
585+ $ bzr branch project
586+ $ bzr split project/library6
587+ $ mv project/library6 .
588+ $ rm project
589+ $ bzr commit -m "split library6 into its own library."
590+
591+Case 18
592+~~~~~~~
593+Henning wants to update to receive Gary's latest changes.
594+
595+Example commands::
596+
597+ $ bzr merge -d library6
598+
599+Case 19
600+~~~~~~~
601+Gary wants to update to receive Henninge's changes, including splitting a
602+library out.
603+
604+Example commands::
605+
606+ $ bzr split --nested project/library6
607+ $ bzr commit project -m "Turned library6 into a library"
608+ $ bzr merge -d project/library6 http://library6
609+ $ bzr commit project -m "Merge Henninge's changes."
610+
611+
612+Case 20
613+~~~~~~~
614+Gary wants to update to receive Henninge's changes, without splitting a library
615+out.
616+
617+ $ bzr split --nested project/library6
618+ $ bzr commit project -m "Turned library6 into a library"
619+ # i.e. a cherrypick that skips the revision where library6 became a library.
620+ $ bzr merge -d project/library6 http://library6 -r 5..-1
621+ $ bzr commit project -m "Merge Henninge's changes."
622+
623+Case 21
624+~~~~~~~
625+
626+John works on a project called FooBar, but has decided that it would be better
627+structured as two projects, where Bar is a library that may be of general use
628+outside of Foo. As it happens, bar already has its own subdirectory.
629+
630+He runs:
631+::
632+
633+ # Convert into two trees: foobar and foobar/bar.
634+ # In each tree, files will be removed and deleted. In foobar/bar, "bar"
635+ # will have been moved to become the tree root.
636+ # These changes will be committed later.
637+ $ bzr upgrade foobar --format=subbranches
638+ $ bzr split foobar/bar
639+
640+ # Add a tree-reference from foobar to foobar/bar, change bar's branch
641+ # to a reference to subbranch in foobar's branch.
642+ $ bzr join --nested foobar/bar
643+
644+ # This recurses into foobar/bar and commits the deletion of the containing
645+ # tree. In foobar, it commits a kind change for 'bar' from directory to
646+ # tree-reference, and the deletion of the contents of bar.
647+ $ bzr commit foobar
648+
649+This commits new revisions to foobar and bar, and foobar's tree-reference bar
650+refers to the revision-id of bar.
651+
652+Next, he adds two new files: foobar/baz and foobar/bar/qux::
653+
654+ $ vi foobar/baz
655+ $ vi foobar/bar/qux
656+ # This adds qux to foobar/bar and adds baz to foobar.
657+ $ bzr add foobar
658+
659+Since foobar/bar/qux is in a commitable state and foobar/baz is not, he invokes
660+::
661+
662+ $ bzr commit foobar/bar
663+
664+This commits foobar/bar/baz/qux to the subtree and commits foobar/bar to the
665+containing tree.
666+
667+(Had he wanted to commit to just the subtree, or just the containing tree, he
668+could have specified an option.)
669+
670+
671+Case 21
672+~~~~~~~
673+
674+Robert wants to hack on a project, Baz, that is structured as a nested tree,
675+which uses the library "quxlib", from quxlib.org.
676+
677+He runs:
678+::
679+
680+ $ bzr branch http://baz.org/dev baz
681+
682+This creates a "subbranches" branch and working tree for baz, as normal. Since
683+tree-references were encountered, it adds subbranches for them to the baz
684+branch. All data is retrieved from baz.org, not quxlib.org.
685+
686+It creates a working tree for quxlib with a subbranch-reference. It uses the
687+revision-id from the tree-reference in the containing tree, not the head
688+revision at baz.org. This allows Robert to get a known-good nested tree.
689+
690+Later, Robert decides to update the version of quxlib being used to the latest
691+from quxlib.org. He runs::
692+
693+ $ bzr pull -d http://quxlib.org
694+
695+This updates the version of quxlib in the working tree, which mean that baz is
696+now out-of-date with its last-committed tree. Unfortunately, the new rev on
697+quxlib is not completely compatible with the old one, and Robert must tweak a
698+few files before Baz runs properly. Once he has done so, he runs::
699+
700+ $ bzr commit baz
701+
702+Now he has committed a known-good nested tree, and the baz working tree is once
703+again up-to-date.
704+
705+
706+User documentation
707+******************
708+
709+For many large projects, it is often useful to incorporate libraries
710+maintained elsewhere or to construct them from multiple subprojects.
711+While it is easy for a single user to set up a particular layout of
712+multiple branches by hand, the different branches really need to be
713+linked together if others are to reproduce the desired layout, and
714+if the relationships are going to be managed over time.
715+
716+Bazaar has good support for building and managing external libraries
717+and subprojects via a feature known as *nested trees*. In particular,
718+nearly all of Bazaar's commonly used commands understand nested trees
719+and Do The Right Thing as explained below. The relationship is hierarchical:
720+the containing tree knows about its nested trees, but nested trees are unaware
721+of the tree (or trees) containing them.
722+
723+At the moment, *nested trees* are the only type of nested item
724+supported though *nested files* may be supported in the future.
725+Nested trees may contain other nested trees as required.
726+
727+Note: This feature requires a recent branch format such as ``2.0``
728+or later.
729+
730+
731+Nesting an external project
732+---------------------------
733+
734+To link an external project into a branch, use the ``branch`` command
735+with the ``--nested`` option like this::
736+
737+ bzr branch --nested SOURCE-URL TARGET-DIR
738+
739+For example, assuming you already have a ``src/lib`` directory where
740+libraries are kept::
741+
742+ bzr branch --nested http://example.com/xmlsaxlib src/lib/sax
743+
744+This will create a nested branch in the ``src/lib/sax`` directory,
745+join it into the containing branch and save the source location.
746+
747+If you now run ``bzr status``, it will show the nested branch as
748+uncommitted changes like this::
749+
750+ + src/lib/sax
751+ + src/lib/sax/README
752+ + src/lib/sax/parser.py
753+ ...
754+
755+To record this change, use the ``commit`` command as you normally would::
756+
757+ bzr commit -m "added SAX parsing library"
758+
759+Note that Bazaar stores the tip revision of each nested branch. This
760+is an important feature in that it's then easy to reproduce the exact
761+combination of libraries used for historical revisions. It also means
762+that other developers pulling or merging your changes will get nested
763+branches created for them at the right revisions of each.
764+
765+
766+Refreshing a nested branch
767+--------------------------
768+
769+As bugs are fixed and enhancements are made to nested projects, you
770+will want to update the version being used. To do this, ``pull`` the
771+latest version of the nested branch. For example::
772+
773+ bzr pull -d src/lib/sax
774+
775+If the latest revision is too unstable, you can always use the ``-r``
776+option on the ``pull`` command to nominate a particular revision or tag.
777+
778+Now that you have the required version of the code, you can make
779+any required adjustments (e.g. API changes), run your automated tests
780+and commit something like this::
781+
782+ view src/lib/sax/README
783+ (hack, hack, hack)
784+ make test
785+ bzr commit -m "upgraded SAX library to version 2.1.3"
786+
787+
788+Changing a nested tree
789+----------------------
790+
791+As well as keeping track of which revisions of external libraries
792+are used over time, one of the reasons for nesting projects is to
793+make minor changes. You may want to do this in order to fix and
794+track particular bugs you need addressed. In other cases, you may want
795+to make various local enhancements that aren't valuable outside
796+the context of your project.
797+
798+As support for nested branches is integrated into most commonly
799+used commands, this is actually quite easy to do: simply make
800+the change to the required files as you normally would! For example::
801+
802+ edit src/lib/sax/parser.py
803+ bzr commit -m "fix bug #42 in sax parser"
804+
805+Note that Bazaar is smart enough to recurse by default into nested
806+branches, commit changes there, and commit the new nested branch tips
807+in the current branch. Both commits get the same commit message.
808+
809+If you want to only commit the change to a nested branch for now, you
810+can change into the nested branch before running commit like this::
811+
812+ cd src/lib/sax
813+ bzr commit -m "fix bug #42 in sax parser"
814+
815+Alternatively, you can use a selective commit like this::
816+
817+ bzr commit -m "fix bug #42 in sax parser" src/lib/sax
818+
819+
820+Reviewing nested tree changes
821+-----------------------------
822+
823+Just like ``commit``, the ``status`` and ``diff`` commands implicitly
824+recurse into nested trees. In the case of ``status``, it shows both the
825+nested tree as having a pending change as well as the items within it that have
826+changed. For example::
827+
828+ M src/lib/sax
829+ M src/lib/sax/parser.py
830+
831+Once again, if you change into a nested tree though, ``status`` and
832+``diff`` will operate just on that tree and not recurse upwards by
833+default.
834+
835+
836+Browsing nested tree history
837+----------------------------
838+
839+As the branches of nested trees have their own history, the ``log`` command
840+shows just the history of the containing branch. To see the history for
841+a nested branch, nominate the branch explicitly like this::
842+
843+ bzr log src/lib/sax
844+
845+Note however that ``log -v`` and ``log -p`` on the containing branch
846+will show what files in nested branches were changed in each revision.
847+
848+
849+Splitting out a project
850+-----------------------
851+
852+If you already have a large project and wish to partition it into
853+reusable subprojects, use the ``split`` command. This takes an existing
854+directory and makes it a separate branch. For example, imagine you have
855+a directory holding UI widgets that another project would like to
856+leverage. You can make it a separate branch like this::
857+
858+ bzr split src/uiwidgets
859+
860+To make the new project available to others, push it to a shared location
861+like this::
862+
863+ cd src/uiwidgets
864+ bzr push bzr://example.com/uiwidgets
865+
866+You also need to link it back into the original project as a nested branch
867+using the ``join`` command like this (assuming the current directory is
868+``src/uiwidgets``)::
869+
870+ bzr join --nested .
871+ bzr commit -m "uiwidgets is now a nested project"
872+
873+Similar to ``branch --nested``, ``join --nested`` joins the nominated directory
874+(which must hold a branch) into the containing tree. In order to make sure
875+that all versions of a tree can be reproduced, the branches of nested trees
876+share a repository with their containing tree.
877+
878+
879+Virtual projects
880+----------------
881+
882+By design, Bazaar is strict about tracking the actual revisions used of
883+nested branches over time. Without this, projects cannot accurately
884+reproduce exactly what was used to make a given build. There are
885+isolated use cases though where is advantageous to say "give me the
886+latest tip of these loosely coupled branches". To do this, create a
887+small 'virtual project' which is just a bunch of *unpegged* nested
888+branches. To mark nested branches as unpegged, use the ``--no-pegged``
889+option of the ``join`` command like this::
890+
891+ bzr join --nested --no-pegged [DIR]
892+
893+To stop the nested branch tips from floating and to begin recording
894+the tip revisions again, use the ``pegged`` option::
895+
896+ bzr join --nested --pegged [DIR]
897+
898+After changing whether one or more nested branches are pegged or not, you
899+need to ``commit`` the branch to record that metadata. (The pegged state
900+is recorded over time.)
901+
902+For example, you may be managing a company intranet site as a project
903+which is nothing more than a list of unrelated departmental websites
904+bundled together. You can set this up like this::
905+
906+ bzr init intranet-site
907+ cd intranet-site
908+ bzr branch bzr://ourserver/websites/research
909+ bzr branch bzr://ourserver/websites/development
910+ bzr branch bzr://ourserver/websites/support
911+ bzr branch bzr://ourserver/websites/hr
912+ bzr join --nested --no-pegged research
913+ bzr join --nested --no-pegged development
914+ bzr join --nested --no-pegged support
915+ bzr join --nested --no-pegged hr
916+ bzr commit -m "initial configuration of intranet-site"
917+
918+Publishing the overall site is then as easy as going to the server
919+hosting your intranet and running something like::
920+
921+ bzr branch http://mymachine//projects/intranet-site
922+
923+Refreshing the overall site is as easy as::
924+
925+ bzr pull
926+
927+Virtual projects are also useful for providing a partial 'view' over
928+a large project containing a large number of subprojects. For example,
929+you may be working on an office suite and have a bunch of developers
930+that only care about the word processor. You can create a virtual
931+project for them like this::
932+
933+ bzr init wp-modules
934+ cd wp-modules
935+ bzr branch ../common
936+ bzr branch ../printing
937+ bzr branch ../spellchecker
938+ bzr branch ../wordprocessor
939+ bzr join --nested --no-pegged common
940+ bzr join --nested --no-pegged printing
941+ bzr join --nested --no-pegged spellchecker
942+ bzr join --nested --no-pegged wordprocessor
943+ bzr commit -m "initial configuration of wp-modules"
944+
945+Those developers can then get bootstrapped faster and have *just* the
946+subprojects they care about by branching from ``wp-modules``.
947+
948+
949+Nested branch tips & tricks
950+---------------------------
951+
952+As explained above, most of Bazaar's commonly used commands recurse
953+downwards into nested branches by default. To prevent this recursion,
954+use the ``--no-recurse-nested`` option on various commands (including
955+``commit``, ``status`` and ``diff``) that support it.
956+
957+Thanks to plugins like bzr-svn and bzr-git, Bazaar has strong support
958+for transparently accessing branches managed by foreign VCS tools. This
959+means that Bazaar can support projects where nested branches are hosted
960+in supported foreign systems. For example, to nest a library maintained
961+in Subversion::
962+
963+ bzr branch --nested svn://example.com/xmlhelpers src/lib/xmlhelpers
964+
965+If you want revisions to be committed both to a remote location and a
966+local location, make the top-level branch a bound branch. (Nested branches
967+have no configuration of their own.)
968+
969+Most likely, you will have some branches that are identical to their upstream
970+version and can be pulled, and some that have local changes and must be merged.
971+You can update all of them at once using ``merge --pull``. This will pull
972+into the trees with no local changes, and merge into the ones with local
973+changes. Afterward, you should commit, which will commit only into the
974+trees that were merged into.
975+
976+As you'd expect, a nested branch can be moved or deleted using the
977+normal commands. For example, after splitting out a subproject, you
978+may want to change its location like this::
979+
980+ bzr mv src/uiwidgets src/lib/uiwidgets
981+ bzr commit -m "move uiwidgets into src/lib"
982+
983+Things to be aware of
984+---------------------
985+
986+Commands like ``commit`` and ``push`` need online access to the locations
987+for nested branches which have updated their tip. In particular, ``commit``
988+will update any changed nested branches first and only commit to the
989+containing branch if all nested branch commits succeed. If you are working
990+offline, you may want to ensure you have a local mirror location defined
991+for nested branches you are likely to tweak. Alternatively, the
992+``no-recurse-nested`` option to the ``commit`` command might to useful to
993+commit some changes, leaving the nested branch commits until you are back
994+online.
995+
996+A given top level tree cannot contain multiple copies of a nested tree.
997+As a consequence, you cannot nest two projects if they both nest
998+the same project somewhere within them. This limitation may be removed
999+in the future. In the meantime, consider restructuring things so that each
1000+project is only nested once (and leverage symbolic links as appropriate).
1001+In most programming environments, having different parts of the project
1002+using different versions of a library is an integration no-no anyhow,
1003+so enforcing *one* common revision is the right way to prevent this from
1004+happening.
1005+
1006+At the moment, nested trees need to be incorporated as a whole.
1007+Filtered views can to used to restrict the set of files and directories
1008+logically seen. Currently though, filtered views are a lens onto a tree:
1009+they do not delete other files and the exposed files/directories must
1010+have the same paths as they do in the original branch. In the future,
1011+we may add support for nesting and moving selected files from a
1012+(read-only) nested branch something like this::
1013+
1014+ bzr nested DIR --file LICENSE --file doc/README::README
1015+ bzr commit -m "change which files are nested from project DIR"
1016+
1017+If you require this feature, please contact us with your needs.
1018+
1019+Design decisions
1020+****************
1021+
1022+The branches of subtrees shall share a repository with the containing tree.
1023+
1024+The branches of subtrees shall be in a special format that shares a single
1025+last_revision file that is stored in the containing branch.
1026+
1027+The subtree branches shall be referenced in the last_revision file by file-id.
1028+
1029+Subtree branches shall not support individual configuration.
1030+
1031+Fetch shall automatically fetch the revisions mentioned by tree-references,
1032+recursively.
1033+
1034+The reserved revision-id "head:" shall be used in tree-references to refer to
1035+the tip revision of a branch.
1036+
1037+bzr-svn repositories with externals shall behave as though the multiple
1038+repositories were a single Bazaar repository with multiple branches.
1039
1040 Shall commands recurse downwards by default?
1041 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1042@@ -76,10 +1000,10 @@
1043 - It is hard to accidentally produce inconsistent trees
1044 - Inconsistent trees are hard for remote users to handle
1045 - Accidentally committing too many things at once is easy to resolve
1046+ - It is hard to accidentally commit too many things at once
1047
1048 Cons:
1049
1050- - It is hard to accidentally commit too many things at once
1051 - Accidentally committing nuclear launch codes is easier to do
1052 - More risk of exposing users to bugs
1053 - Makes incompleteness more glaring
1054@@ -98,8 +1022,8 @@
1055
1056 - the "name" of subbranches can change from revision to revision. In fact,
1057 subbranches may have no name in a given revision.
1058- - a user may want to get revision X of a subbranch named "foo" in revision Y of
1059- the top branch.
1060+ - a user may want to get revision X of a subbranch named "foo" in revision Y
1061+ of the top branch.
1062
1063 The syntax will be ``BRANCH#SUBBRANCH``, e.g. ``lp:bigproject#subproject``.
1064 ``BRANCH`` is a regular URL and ``SUBBRANCH`` is a path within BRANCH's tree
1065@@ -114,8 +1038,9 @@
1066 cross subtree boundaries, e.g. a merge in the top tree can move a file between
1067 subtrees.
1068
1069-The downside is that we can't have cheap support for subtrees that are copies of
1070-one another, because we wouldn't know which copy to apply sets of changes to.
1071+The downside is that we can't have cheap support for subtrees that are copies
1072+of one another, because we wouldn't know which copy to apply sets of changes
1073+to.
1074
1075
1076 Shall we use root-ids for tree references?
1077@@ -136,8 +1061,8 @@
1078 ~~~~~~~~~~~~~~~~~~~~~~~~~~
1079
1080 Yes. It matches existing behaviour by failing earlier, and the extra cost does
1081-not seem onerous. (To be fully efficient this requires an index of the subtrees,
1082-otherwise we need to scan the fully inventory/dirstate.)
1083+not seem onerous. (To be fully efficient this requires an index of the
1084+subtrees, otherwise we need to scan the fully inventory/dirstate.)
1085
1086 (Also, this decision can be changed later with no compatibility concerns.)
1087
1088@@ -149,17 +1074,19 @@
1089 local last revision's revno would change (i.e. is a non-lhs parent in the merge
1090 source). This is expected to be the most common way to update nested trees.
1091
1092-The existing "bzr merge --pull" behaviour will be renamed to "bzr merge --pull-renumber".
1093+The existing "bzr merge --pull" behaviour will be renamed to "bzr merge
1094+--pull-renumber".
1095
1096-"bzr merge" (with no "--pull") will do a merge in all trees. "bzr pull" will do
1097-a pull in all trees.
1098+"bzr merge" (with no "--pull") will do a merge in all trees. "bzr pull" will
1099+do a pull in all trees.
1100
1101 The rationale is that a very common use-case is that the top tree is a project
1102 the user is actively committing to, and the subtrees are mainly libraries that
1103-are being mirrored. So a behaviour that forced every update to be a merge would
1104-be undesirable for the mirrored subtrees, but an update that is a pull wouldn't
1105-suit the changing top tree. And the existing "merge --pull" (that can renumber
1106-revisions) isn't desireable for either the top tree or subtrees in this case.
1107+are being mirrored. So a behaviour that forced every update to be a merge
1108+would be undesirable for the mirrored subtrees, but an update that is a pull
1109+wouldn't suit the changing top tree. And the existing "merge --pull" (that can
1110+renumber revisions) isn't desireable for either the top tree or subtrees in
1111+this case.
1112
1113
1114 What should uncommit do?
1115@@ -175,7 +1102,14 @@
1116 $ bzr uncommit
1117
1118 will not cause a change in subtrees, since the top-level commit did not affect
1119-them.
1120+them. But on the other hand:
1121+
1122+ $ echo foo > subtree/versioned-file-in-subtree.txt
1123+ $ bzr ci -m "Change file"
1124+ $ bzr uncommit
1125+
1126+will first commit to the subtree, then to the top tree. The uncommit will
1127+restore both trees to their previous state.
1128
1129
1130 Shall we use a CompositeTree object as a shim to make existing commands work?
1131@@ -189,13 +1123,10 @@
1132 Some subtrees should have commits and some should not. How?
1133 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1134
1135-We won't do this initially. Flagging some sub-trees as mirror-only or similar
1136-sounds like a nice feature, but we can add this later (and it may only require a
1137-working tree format bump to add).
1138-
1139-It would be nice to have more infrastructure in general to handle mirrors, and
1140-this is not specific to nested trees.
1141-
1142+We will not provide special support for this initially. We might later support
1143+flagging some sub-trees as mirror-only something similar, but this seems like
1144+it could be a general feture not specific to nesting. (and it may only require
1145+a working tree format bump to add).
1146
1147 How do we handle files that are moved into subtrees (from another tree in the same top tree)?
1148 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1149@@ -203,128 +1134,97 @@
1150 Add a revision property:
1151 "Files-from-other-trees: (rev-id: [f-id, ...]), ..."
1152
1153-(Once we can do cherry-pick merges, we might use those instead?)
1154-
1155-
1156-
1157-Handling svn:externals
1158-~~~~~~~~~~~~~~~~~~~~~~
1159-
1160-svn externals commonly have references to the tip of some other branch.
1161-Because we want a deterministic representation of the inventory when
1162-pulling from svn, we can't put the specific revision-id into the inventory
1163-at that time. However, we do want to bring down all the relevant data at
1164-the time of fetching, so that we can later branch locally. This seems to
1165-
1166-Decided questions
1167-*****************
1168-
1169-The branches of subtrees shall share a repository with the containing tree.
1170-
1171-The branches of subtrees shall be in a special format that shares a single
1172-last_revision file that is stored in the containing branch.
1173-
1174-The subtree branches shall be referenced in the last_revision file by file-id.
1175-
1176-Subtree branches shall not support individual configuration.
1177-
1178-Fetch shall automatically fetch the revisions mentioned by tree-references,
1179-recursively.
1180-
1181-The reserved revision-id "head:" shall be used in tree-references to refer to
1182-the tip revision of a branch.
1183-
1184-bzr-svn repositories with externals shall behave as though the multiple
1185-repositories were a single Bazaar repository with multiple branches.
1186-
1187-
1188-Use Cases
1189-*********
1190-
1191-Case 1
1192-~~~~~~
1193-Barry works on a project with three libraries. He wants to keep up to date
1194-with the tip of those libraries, but he doesn't want them to be part of his
1195-source tree.
1196-
1197-Case 2
1198-~~~~~~
1199-Now, Barry wants to add a fourth library.
1200-
1201-Case 3
1202-~~~~~~
1203-Barry wants to publish his project.
1204-
1205-Case 4
1206-~~~~~~
1207-Barry decides to make part of his project into another library
1208-
1209-Case 5
1210-~~~~~~
1211-Curtis wants to hack on Barry's project
1212-
1213-Case 6
1214-~~~~~~
1215-Barry wants to drop one of the libraries he was using
1216-
1217-Case 7
1218-~~~~~~
1219-Curtis has made changes to one of the libraries. Barry wants to merge Curtis'
1220-changes into his copy.
1221-
1222-Case 8
1223-~~~~~~
1224-Curtis has made changes to Barry's main project. Barry wants to merge Curtis'
1225-changes into his copy.
1226-
1227-Case 9
1228-~~~~~~
1229-Barry makes changes in his project and in a library, and he runs status
1230-
1231-Case 10
1232-~~~~~~~
1233-Barry wants to upgrade the bazaar format of his project
1234-
1235-Case 11
1236-~~~~~~~
1237-Curtis wants to apply Barry's latest changes.
1238-
1239-Case 12
1240-~~~~~~~
1241-Danilo wants to start a project with two libraries using nested trees from
1242-scratch.
1243-
1244-Case 13
1245-~~~~~~~
1246-Edwin has a project that doesn't use nested trees and he wants to start using
1247-nested trees.
1248-
1249-Case 14
1250-~~~~~~~
1251-Françis has a project with nested trees where the containing tree uses one
1252-Bazaar format and the subtree uses a different Bazaar format.
1253-
1254-Case 15
1255-~~~~~~~
1256-Barry commits some changes to a library and to the main project, and then
1257-discovers the changes are not appropriate.
1258-
1259-Case 16
1260-~~~~~~~
1261-Gary is writing a project. Henninge wants to split a library out of it.
1262-
1263-Case 17
1264-~~~~~~~
1265-Henning wants to update to receive Gary's latest changes.
1266-
1267-Case 18
1268-~~~~~~~
1269-Gary wants to update to receive Henninge's changes, including splitting a
1270-library out.
1271-
1272-Case 19
1273-~~~~~~~
1274-Gary wants to update to receive Henninge's changes, without splitting a library
1275-out.
1276+(Once we can record cherry-pick merges, we might use those instead, but it
1277+depends on their history-fetching requirements.)
1278+
1279+
1280+
1281+
1282+Comparison with other systems
1283+*****************************
1284+
1285+Git submodules
1286+~~~~~~~~~~~~~~
1287+
1288+This allows separate repositories to be used for submodules. At the UI layer,
1289+they are quite different, because submodules does not attempt to integrate
1290+subtree support into the core commands.
1291+
1292+Mercurial Forests
1293+~~~~~~~~~~~~~~~~~
1294+
1295+The wiki page does not give confidence that this is a well-maintained project.
1296+It seems similar to config-manager-- its 'snapshot' files are like
1297+config-manager's config files, describing what branches to get and where to put
1298+them, optionally specifying a revision. No metadata about nesting is stored in
1299+the tree. Optionally, a 'snapshot.txt' file may be stored in the containing
1300+tree, but it can also be stored somewhere else.
1301+
1302+There is no attempt to integrate subtree support into the core commands.
1303+
1304+Mercurial Nested Repositories
1305+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1306+This design was for an integrated feature, but there are apparently 4
1307+implementations as extensions. While it does integrate subtree support into
1308+core commands, this may be off by default: "The alternative that I lean towards
1309+is to not recurse unless explicitly instructed to. Most probably, only a few
1310+commands should arguably even be aware of modules."
1311+
1312+Command comparison:
1313+
1314+- hg module add ~= bzr join --nested
1315+- hg module remove ~= bzr remove --keep
1316+- hg module record's functionality is part of nested commits in nested trees.
1317+
1318+Like submodules, this stores location information in versioned data: a
1319+.hgmodules directory.
1320+Like submodules and nested trees, particular revisions are recorded.
1321+
1322+Subversion "svn:externals"
1323+~~~~~~~~~~~~~~~~~~~~~~~~~~
1324+Like bzr, uses per-file metadata. Like submodules and nested repositories,
1325+locations are versioned data. Like Forests, revisions are optional. Like
1326+nested repositories, there is limited integration into core commands; checkout
1327+and update support externals, and commit may support them in the future.
1328+However, there is no UI specific to creating and updating svn:externals
1329+references.
1330+
1331+Unlike all other alternatives, supports partial checkouts. This is because svn
1332+natively supports partial checkouts. Also, supports checkouts of tags, because
1333+tags are merely a convention in svn.
1334+
1335+Supports pulling in "head" subtrees too, not just specific ("known-good")
1336+revisions. Nested trees supports this in order to provide high-fidelity
1337+imports.
1338+
1339+Some support for single-file svn:externals (see
1340+http://subversion.tigris.org/svn_1.6_releasenotes.html#externals), whereas bzr
1341+subtrees must be directories.
1342+
1343+Has a --ignore-externals option for checking out without pulling in the
1344+svn:externals items (svn checkout is more or less equivalent to bzr branch).
1345+You can also use that option on update (more or less like bzr merge).
1346+
1347+
1348+Comments on differences
1349+~~~~~~~~~~~~~~~~~~~~~~~
1350+externals support partial checkouts. Nested trees could gain support for this
1351+once Bazaar itself supports partial checkouts. Supporting a single file as a
1352+"subtree" would also depend on native bzr support. On platforms that support
1353+symlinks, using symlinks to portions of a subtree can be an effective
1354+substitute.
1355+
1356+
1357+Future work
1358+***********
1359+It would be nice to support multiple copies of subtree in a master tree.
1360+Currently, this would lead to having multiple copies of a given file-id in the
1361+(composite) tree, which is forbidden. Allowing this would involve one of:
1362+
1363+- permitting multiple copies of a file-id within a tree
1364+- not treating nested trees as composite trees
1365+- using fake file-ids within the composite tree
1366+- replacing the file-id concept with something else (e.g. path tokens)
1367+
1368
1369 .. vim: ft=rst

Subscribers

People subscribed via source and target branches

to all changes: