how do i use "bzr join" correctly ?

Asked by John Frankland

I am new to bazaar and am trying to convert my old CVS-controlled project to bazaar for launchpad.
I read in the user's guide that "bzr join" will take an existing tree and make it part of another tree.
I have two bazaar trees - let's call them TreeA and TreeB. I want to join them together so that the
top level of TreeB is in the top level of TreeA.

Initially I have two (bazaar-controlled) directories, TreeA and TreeB.
Then I do

cp -R TreeB TreeA/
cd TreeA
bzr join TreeB

and I get the following error:

bzr: ERROR: Cannot join TreeB. Trees have the same root

What am I doing wrong ?
Thanks a lot for your help.

Question information

Language:
English Edit question
Status:
Answered
For:
Bazaar Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Amr El-Sharnoby (amr-el-sharnoby) said :
#1

This page can help you I think;
http://bazaar-vcs.org/NestedTreesDesign

Revision history for this message
John Frankland (frankland) said :
#2

Thanks for the reply, however I'm still not sure of the answer. My question might not be clear enough.
After I "join" TreeA and TreeB together (with TreeB becoming a subdirectory of TreeA), I want to forget that they were ever separate, i.e. I want to permanently make TreeB a subdirectory of TreeA
(but keeping the full history of both A & B).
I probably misunderstood, but reading the page you cite I get the impression that "bzr join --reference" is a sort of 'symbolic link' between the two, rather than a merge?
Sorry if I'm totally missing the point.
Thanks a lot.

Revision history for this message
Martin Pool (mbp) said :
#3

John: I think in this case you should actually just merge the two branches ("merge ../treeB"), then rename the files into subdirectories to suit.

Revision history for this message
John Frankland (frankland) said :
#4

Hi Martin. Thanks for the answer, but when I try what you suggest I get the following error:
[frankland@ganp571 treeA]> bzr merge ../treeB
bzr: ERROR: Branches have no common ancestor, and no merge base revision was specified.

if i copy treeB into the treeA directory and use "merge" I get the same error:
[frankland@ganp571 treeA]> bzr merge treeB
bzr: ERROR: Branches have no common ancestor, and no merge base revision was specified.

if i copy treeB into the treeA directory and use "join" I get
[frankland@ganp571 treeA]> bzr join treeB
bzr: ERROR: Cannot join treeB. Trees have the same root

if I leave treeB outside treeA and do "join" like this :
[frankland@ganp571 treeA]> bzr join ../treeB
bzr: ERROR: Not a branch: "/home/frankland/bzr-join-test/".

(bzr-join-test is just a simple directory in which I created the two bzr-controlled directories treeA and treeB).

I don't understand at all what I am supposed to do!

Revision history for this message
John Frankland (frankland) said :
#5

(Continues message above)

if I copy treeB inside treeA and try join --reference I get:
[frankland@ganp571 treeA]> bzr join --reference treeB
bzr: ERROR: Cannot join treeB. Trees have the same root id.

if i leave treeB outside I get:
[frankland@ganp571 treeA]> bzr join --reference ../treeB
bzr: ERROR: Not a branch: "/home/frankland/bzr-join-test/".

Revision history for this message
John Frankland (frankland) said :
#6

Thanks to the example of use given in Bug#308562 (see "Related bugs"), I have finally found a working solution, which I give here for future reference. It would be very helpful to add something like this to the User Reference...

Note: I am using bazaar v1.13.1 on Ubuntu 9.04

In order to be able to use 'bzr join' to make a previously independent tree become an integral subdirectory of another tree, while preserving the history of both,
both trees must be in format "rich-root-pack".
As my trees were created (by tailor) with default format "pack-0.92", I had to do a "bzr upgrade --format=rich-root-pack" on each.

Both of my trees were created as "stand-alone" repositories, however I moved them inside a shared repository before doing the join (created with "bzr init-repo --format=rich-root-pack").
So then I had the following structures on disk:

~/MyRepo (shared repository)
~/MyRepo/ProjectMainDir (the tree corresponding to the top level directory of my project)
~/MyRepo/ProjectSubDir (the tree containing the subdirectory of my project, which I want to put back inside MainDir)

Then I did:
(starting in ~/MyRepo)
bzr branch ProjectMainDir Project.merge
cd Project.merge
bzr branch ../ProjectSubDir SubDir
bzr join SubDir
bzr commit

and it all works!
Cheers
John

Revision history for this message
John Frankland (frankland) said :
#7

No, sorry, spoke too fast!!!
All went well for the first subdirectory as shown above, however when I try to add a second subdirectory in exactly the same way I get the following error:

bzr join SubDir2
bzr: ERROR: File id {TREE_ROOT} already exists in inventory as InventoryDirectory('TREE_ROOT', u'ProjectSubDir', parent_id='tree_root-20090522124002-yuqlri6cb9p1q13a-1', revision=None)

I can't find any information on this error or what to do. Can someone please help me ?

Revision history for this message
James Teh (jteh) said :
#8

I encountered this problem as well today, but only in certain situations. I finally figured out what was going on.

First, if you join two trees which were both rich-root right from creation (i.e. not upgraded to rich-root), it will work just fine. In your case, your first branch was cloned into a rich-root repository, so that is fine. However, when you clone a branch *inside* another branch, it isn't linked into the shared repository. That is, if you clone a non-rich-root branch while inside a rich-root branch, the cloned branch won't be rich-root. This explains why your second join attempt failed.

The reason appears to be that bzr doesn't set a unique root ID for a branch unless it was *created* as a rich-root branch. That is, if you create a non-rich-root branch, the root ID is "tree_root", but even once you convert it with bzr upgrade, it is still "rich_root". In contrast, when you create a branch as rich-root, the root ID is "tree_root-xxxxxxx...", where the bit after the dash is unique.

Herein lies the problem. You've already joined one branch with a root ID of "tree_root", so that is now used. Now you're trying to join another with a root ID of "tree_root", which will fail because that ID already exists.

I guess this is a bug in bzr; it should probably change the tree root when it upgrades a branch to rich-root. However, my understanding of this stuff is somewhat limited, so maybe there's a problem with that.

You can work around this by changing the root ID of the branch you're trying to join (subdir2 in your example). Be warned: I have no idea whether this has any adverse consequences; someone with more understanding of Bazaar's internals will need to answer that. However, you can do it from within Python like this:
>>> import bzrlib.workingtree
>>> bzrlib.workingtree.WorkingTree.open("subdir2").set_root_id("tree_root_subdir2")
bzr join subdir2 should now work.

Hope this helps.

Revision history for this message
Alexander Röhnsch (roehnsch) said :
#9

Thanks a lot! That did it for me, too.

I had two independently created working trees, one of which is a sub dir of the other. They were standard pack-0.92 format. Only after converting them to rich-root-pack and then changing the root id of the sub dir did the join command work as expected.

The problem was already submitted as bug: https://bugs.launchpad.net/bzr/+bug/370710

Revision history for this message
Jurgen Defurne (jurgen-defurne) said :
#10

I tried the above solution and, while the joining works, unfortunately all history of the joined tree is lost, and the operation is flagged as addition of new files. I did upgrade both repositories to 2a format and branched from them.

This statement on the join command :

This is marked as a merge of the subtree into the containing tree, and all history is preserved.

does not seem to work in the case of upgraded (as opposed to initial created) repositories, with changing the tree root by means of the above procedure.

Can you help with this problem?

Provide an answer of your own, or ask John Frankland for more information if necessary.

To post a message you must log in.