452
450
reconciler = BranchReconciler(self, thorough=thorough)
453
451
return reconciler.reconcile()
455
def set_reference_info(self, file_id, branch_location, path=None):
456
"""Set the branch location to use for a tree reference."""
457
raise errors.UnsupportedOperation(self.set_reference_info, self)
459
def get_reference_info(self, file_id, path=None):
460
"""Get the tree_path and branch_location for a tree reference."""
461
raise errors.UnsupportedOperation(self.get_reference_info, self)
463
def reference_parent(self, file_id, path, possible_transports=None):
464
"""Return the parent branch for a tree-reference.
466
:param path: The path of the nested tree in the tree
467
:return: A branch associated with the nested tree
470
branch_location = self.get_reference_info(file_id)[0]
471
except errors.UnsupportedOperation:
472
branch_location = None
473
if branch_location is None:
475
return Branch.open_from_transport(
476
self.controldir.root_transport.clone(path),
477
possible_transports=possible_transports)
478
except errors.NotBranchError:
482
urlutils.strip_segment_parameters(self.user_url), branch_location),
483
possible_transports=possible_transports)
486
454
class BzrBranch8(BzrBranch):
487
455
"""A branch that stores tree-reference locations."""
550
518
def _set_all_reference_info(self, info_dict):
551
519
"""Replace all reference info stored in a branch.
553
:param info_dict: A dict of {file_id: (branch_location, tree_path)}
521
:param info_dict: A dict of {file_id: (tree_path, branch_location)}
556
524
writer = rio.RioWriter(s)
557
for file_id, (branch_location, tree_path) in viewitems(info_dict):
558
stanza = rio.Stanza(file_id=file_id,
525
for tree_path, (branch_location, file_id) in viewitems(info_dict):
526
stanza = rio.Stanza(tree_path=tree_path,
559
527
branch_location=branch_location)
560
if tree_path is not None:
561
stanza.add('tree_path', tree_path)
528
if file_id is not None:
529
stanza.add('file_id', file_id)
562
530
writer.write_stanza(stanza)
563
531
with self.lock_write():
564
532
self._transport.put_bytes('references', s.getvalue())
572
540
with self.lock_read():
573
541
if self._reference_info is not None:
574
542
return self._reference_info
576
with self._transport.get('references') as rio_file:
577
stanzas = rio.read_stanzas(rio_file)
579
s['file_id'].encode('utf-8'): (
580
s['branch_location'],
581
s['tree_path'] if 'tree_path' in s else None)
583
except errors.NoSuchFile:
543
with self._transport.get('references') as rio_file:
544
stanzas = rio.read_stanzas(rio_file)
547
s['branch_location'],
548
s['file_id'].encode('ascii')
549
if 'file_id' in s else None)
585
551
self._reference_info = info_dict
588
def set_reference_info(self, file_id, branch_location, tree_path=None):
554
def set_reference_info(self, tree_path, branch_location, file_id=None):
589
555
"""Set the branch location to use for a tree reference.
557
:param tree_path: The path of the tree reference in the tree.
591
558
:param branch_location: The location of the branch to retrieve tree
593
560
:param file_id: The file-id of the tree reference.
594
:param tree_path: The path of the tree reference in the tree.
596
562
info_dict = self._get_all_reference_info()
597
info_dict[file_id] = (branch_location, tree_path)
563
info_dict[tree_path] = (branch_location, file_id)
598
564
if branch_location is None:
599
del info_dict[file_id]
565
del info_dict[tree_path]
600
566
self._set_all_reference_info(info_dict)
602
def get_reference_info(self, file_id):
568
def get_reference_info(self, path):
603
569
"""Get the tree_path and branch_location for a tree reference.
605
:return: a tuple of (branch_location, tree_path)
607
return self._get_all_reference_info().get(file_id, (None, None))
571
:return: a tuple of (branch_location, file_id)
573
return self._get_all_reference_info().get(path, (None, None))
575
def reference_parent(self, path, file_id=None, possible_transports=None):
576
"""Return the parent branch for a tree-reference file_id.
578
:param file_id: The file_id of the tree reference
579
:param path: The path of the file_id in the tree
580
:return: A branch associated with the file_id
582
branch_location = self.get_reference_info(path)[0]
583
if branch_location is None:
584
return Branch.reference_parent(self, path, file_id,
586
branch_location = urlutils.join(self.user_url, branch_location)
587
return Branch.open(branch_location,
588
possible_transports=possible_transports)
609
590
def set_push_location(self, location):
610
591
"""See Branch.set_push_location."""
705
686
class BzrBranch7(BzrBranch8):
706
687
"""A branch with support for a fallback repository."""
708
def set_reference_info(self, file_id, branch_location, tree_path=None):
709
super(BzrBranch7, self).set_reference_info(
710
file_id, branch_location, tree_path)
711
format_string = BzrBranchFormat8.get_format_string()
712
mutter('Upgrading branch to format %r', format_string)
713
self._transport.put_bytes('format', format_string)
689
def set_reference_info(self, tree_path, branch_location, file_id=None):
690
Branch.set_reference_info(self, file_id, tree_path, branch_location)
692
def get_reference_info(self, path):
693
Branch.get_reference_info(self, path)
695
def reference_parent(self, path, file_id=None, possible_transports=None):
696
return Branch.reference_parent(
697
self, path, file_id, possible_transports)
716
700
class BzrBranch6(BzrBranch7):
991
971
def get_reference(self, a_controldir, name=None):
992
972
"""See BranchFormat.get_reference()."""
993
973
transport = a_controldir.get_branch_transport(None, name=name)
994
url = urlutils.strip_segment_parameters(a_controldir.user_url)
974
url = urlutils.split_segment_parameters(a_controldir.user_url)[0]
995
975
return urlutils.join(
996
976
url, transport.get_bytes('location').decode('utf-8'))
1033
1013
def _make_reference_clone_function(format, a_branch):
1034
1014
"""Create a clone() routine for a branch dynamically."""
1035
def clone(to_bzrdir, revision_id=None, repository_policy=None, name=None,
1015
def clone(to_bzrdir, revision_id=None,
1016
repository_policy=None):
1037
1017
"""See Branch.clone()."""
1038
return format.initialize(to_bzrdir, target_branch=a_branch, name=name)
1018
return format.initialize(to_bzrdir, target_branch=a_branch)
1039
1019
# cannot obey revision_id limits when cloning a reference ...
1040
1020
# FIXME RBC 20060210 either nuke revision_id for clone, or
1041
1021
# emit some sort of warning/error to the caller ?!