130
128
return list(self.get_branches().values())
130
def branch_names(self):
131
"""List all branch names in this control directory.
133
:return: List of branch names
136
self.get_branch_reference()
137
except (errors.NotBranchError, errors.NoRepositoryPresent):
132
142
def get_branches(self):
133
143
"""Get all branches in this control directory, as a dictionary.
152
162
this in the future - for instance to make bzr talk with svn working
155
raise NotImplementedError(self.is_control_filename)
165
return self._format.is_control_filename(filename)
157
167
def needs_format_conversion(self, format=None):
158
168
"""Return true if this controldir needs convert_format run on it.
400
410
raise NotImplementedError(self.sprout)
402
412
def push_branch(self, source, revision_id=None, overwrite=False,
403
remember=False, create_prefix=False, lossy=False):
413
remember=False, create_prefix=False, lossy=False,
404
415
"""Push the source branch into this ControlDir."""
406
417
# If we can open a branch, use its direct repository, otherwise see
425
436
revision_id = source.last_revision()
426
437
repository_to.fetch(source.repository, revision_id=revision_id)
427
br_to = source.sprout(self, revision_id=revision_id, lossy=lossy)
438
br_to = source.sprout(
439
self, revision_id=revision_id, lossy=lossy,
440
tag_selector=tag_selector)
428
441
if source.get_push_location() is None or remember:
429
442
# FIXME: Should be done only if we succeed ? -- vila 2012-01-18
430
443
source.set_push_location(br_to.base)
444
457
tree_to = self.open_workingtree()
445
458
except errors.NotLocalUrl:
446
push_result.branch_push_result = source.push(br_to,
447
overwrite, stop_revision=revision_id, lossy=lossy)
459
push_result.branch_push_result = source.push(
460
br_to, overwrite, stop_revision=revision_id, lossy=lossy,
461
tag_selector=tag_selector)
448
462
push_result.workingtree_updated = False
449
463
except errors.NoWorkingTree:
450
push_result.branch_push_result = source.push(br_to,
451
overwrite, stop_revision=revision_id, lossy=lossy)
464
push_result.branch_push_result = source.push(
465
br_to, overwrite, stop_revision=revision_id, lossy=lossy,
466
tag_selector=tag_selector)
452
467
push_result.workingtree_updated = None # Not applicable
454
469
with tree_to.lock_write():
455
470
push_result.branch_push_result = source.push(
456
471
tree_to.branch, overwrite, stop_revision=revision_id,
472
lossy=lossy, tag_selector=tag_selector)
459
474
push_result.workingtree_updated = True
460
475
push_result.old_revno = push_result.branch_push_result.old_revno
493
508
raise NotImplementedError(self.check_conversion_target)
495
510
def clone(self, url, revision_id=None, force_new_repo=False,
496
preserve_stacking=False):
511
preserve_stacking=False, tag_selector=None):
497
512
"""Clone this controldir and its contents to url verbatim.
499
514
:param url: The url create the clone at. If url's last component does
509
524
return self.clone_on_transport(_mod_transport.get_transport(url),
510
525
revision_id=revision_id,
511
526
force_new_repo=force_new_repo,
512
preserve_stacking=preserve_stacking)
527
preserve_stacking=preserve_stacking,
528
tag_selector=tag_selector)
514
530
def clone_on_transport(self, transport, revision_id=None,
515
531
force_new_repo=False, preserve_stacking=False, stacked_on=None,
516
create_prefix=False, use_existing_dir=True, no_tree=False):
532
create_prefix=False, use_existing_dir=True, no_tree=False,
517
534
"""Clone this controldir and its contents to transport verbatim.
519
536
:param transport: The transport for the location to produce the clone
563
580
controldir = klass.open_from_transport(current_transport)
564
except (errors.NotBranchError, errors.PermissionDenied):
581
except (errors.NotBranchError, errors.PermissionDenied,
582
errors.UnknownFormatError):
567
585
recurse, value = evaluate(controldir)
788
806
a_transport = new_t
791
def open_tree_or_branch(klass, location):
809
def open_tree_or_branch(klass, location, name=None):
792
810
"""Return the branch and working tree at a location.
794
812
If there is no tree at the location, tree will be None.
797
815
:return: (tree, branch)
799
817
controldir = klass.open(location)
800
return controldir._get_tree_branch()
818
return controldir._get_tree_branch(name=name)
803
821
def open_containing_tree_or_branch(klass, location,
1027
1045
_default_format = None
1028
1046
"""The default format used for new control directories."""
1030
_server_probers = []
1031
"""The registered server format probers, e.g. RemoteBzrProber.
1033
This is a list of Prober-derived classes.
1037
1049
"""The registered format probers, e.g. BzrProber.
1124
1136
klass._probers.remove(prober)
1127
def register_server_prober(klass, prober):
1128
"""Register a control format prober for client-server environments.
1130
These probers will be used before ones registered with
1131
register_prober. This gives implementations that decide to the
1132
chance to grab it before anything looks at the contents of the format
1135
klass._server_probers.append(prober)
1137
1138
def __str__(self):
1138
1139
# Trim the newline
1139
1140
return self.get_format_description().rstrip()
1142
1143
def all_probers(klass):
1143
return klass._server_probers + klass._probers
1144
return klass._probers
1146
1147
def known_formats(klass):
1155
1156
def find_format(klass, transport, probers=None):
1156
1157
"""Return the format present at transport."""
1157
1158
if probers is None:
1158
probers = klass.all_probers()
1160
klass.all_probers(),
1161
key=lambda prober: prober.priority(transport))
1159
1162
for prober_kls in probers:
1160
1163
prober = prober_kls()
1247
1250
raise NotImplementedError(self.supports_transport)
1253
def is_control_filename(klass, filename):
1254
"""True if filename is the name of a path which is reserved for
1257
:param filename: A filename within the root transport of this
1260
This is true IF and ONLY IF the filename is part of the namespace reserved
1261
for bzr control dirs. Currently this is the '.bzr' directory in the root
1262
of the root_transport. it is expected that plugins will need to extend
1263
this in the future - for instance to make bzr talk with svn working
1266
raise NotImplementedError(self.is_control_filename)
1250
1269
class Prober(object):
1251
1270
"""Abstract class that can be used to detect a particular kind of
1259
1278
probers that detect .bzr/ directories and Bazaar smart servers,
1262
Probers should be registered using the register_server_prober or
1263
register_prober methods on ControlDirFormat.
1281
Probers should be registered using the register_prober methods on
1266
1285
def probe_transport(self, transport):
1285
1304
raise NotImplementedError(klass.known_formats)
1307
def priority(klass, transport):
1308
"""Priority of this prober.
1310
A lower value means the prober gets checked first.
1314
-10: This is a "server" prober
1316
10: This is a regular file-based prober
1317
100: This is a prober for an unsupported format
1288
1322
class ControlDirFormatInfo(object):
1462
1496
def is_control_filename(filename):
1463
1497
"""Check if filename is used for control directories."""
1464
# TODO(jelmer): Allow registration by other VCSes
1465
return filename == '.bzr'
1498
# TODO(jelmer): Instead, have a function that returns all control
1500
for key, format in format_registry.items():
1501
if format().is_control_filename(filename):
1468
1507
class RepositoryAcquisitionPolicy(object):