1071
934
raise errors.NotBranchError(location)
1072
935
return tree, branch, branch.repository, relpath
1074
def open_repository(self, _unsupported=False):
1075
"""Open the repository object at this BzrDir if one is present.
1077
This will not follow the Branch object pointer - it's strictly a direct
1078
open facility. Most client code should use open_branch().repository to
1079
get at a repository.
1081
:param _unsupported: a private parameter, not part of the api.
1082
TODO: static convenience version of this?
1084
raise NotImplementedError(self.open_repository)
1086
def open_workingtree(self, _unsupported=False,
1087
recommend_upgrade=True, from_branch=None):
1088
"""Open the workingtree object at this BzrDir if one is present.
1090
:param recommend_upgrade: Optional keyword parameter, when True (the
1091
default), emit through the ui module a recommendation that the user
1092
upgrade the working tree when the workingtree being opened is old
1093
(but still fully supported).
1094
:param from_branch: override bzrdir branch (for lightweight checkouts)
1096
raise NotImplementedError(self.open_workingtree)
1098
def has_branch(self, name=None):
1099
"""Tell if this bzrdir contains a branch.
1101
Note: if you're going to open the branch, you should just go ahead
1102
and try, and not ask permission first. (This method just opens the
1103
branch and discards it, and that's somewhat expensive.)
1106
self.open_branch(name)
1108
except errors.NotBranchError:
1111
def has_workingtree(self):
1112
"""Tell if this bzrdir contains a working tree.
1114
This will still raise an exception if the bzrdir has a workingtree that
1115
is remote & inaccessible.
1117
Note: if you're going to open the working tree, you should just go ahead
1118
and try, and not ask permission first. (This method just opens the
1119
workingtree and discards it, and that's somewhat expensive.)
1122
self.open_workingtree(recommend_upgrade=False)
1124
except errors.NoWorkingTree:
1127
937
def _cloning_metadir(self):
1128
938
"""Produce a metadir suitable for cloning with.
1187
997
format.require_stacking()
1190
def checkout_metadir(self):
1191
return self.cloning_metadir()
1193
def sprout(self, url, revision_id=None, force_new_repo=False,
1194
recurse='down', possible_transports=None,
1195
accelerator_tree=None, hardlink=False, stacked=False,
1196
source_branch=None, create_tree_if_local=True):
1197
"""Create a copy of this bzrdir prepared for use as a new line of
1200
If url's last component does not exist, it will be created.
1202
Attributes related to the identity of the source branch like
1203
branch nickname will be cleaned, a working tree is created
1204
whether one existed before or not; and a local branch is always
1207
if revision_id is not None, then the clone operation may tune
1208
itself to download less data.
1209
:param accelerator_tree: A tree which can be used for retrieving file
1210
contents more quickly than the revision tree, i.e. a workingtree.
1211
The revision tree will be used for cases where accelerator_tree's
1212
content is different.
1213
:param hardlink: If true, hard-link files from accelerator_tree,
1215
:param stacked: If true, create a stacked branch referring to the
1216
location of this control directory.
1217
:param create_tree_if_local: If true, a working-tree will be created
1218
when working locally.
1220
target_transport = get_transport(url, possible_transports)
1221
target_transport.ensure_base()
1222
cloning_format = self.cloning_metadir(stacked)
1223
# Create/update the result branch
1224
result = cloning_format.initialize_on_transport(target_transport)
1225
# if a stacked branch wasn't requested, we don't create one
1226
# even if the origin was stacked
1227
stacked_branch_url = None
1228
if source_branch is not None:
1230
stacked_branch_url = self.root_transport.base
1231
source_repository = source_branch.repository
1234
source_branch = self.open_branch()
1235
source_repository = source_branch.repository
1237
stacked_branch_url = self.root_transport.base
1238
except errors.NotBranchError:
1239
source_branch = None
1241
source_repository = self.open_repository()
1242
except errors.NoRepositoryPresent:
1243
source_repository = None
1244
repository_policy = result.determine_repository_policy(
1245
force_new_repo, stacked_branch_url, require_stacking=stacked)
1246
result_repo, is_new_repo = repository_policy.acquire_repository()
1247
is_stacked = stacked or (len(result_repo._fallback_repositories) != 0)
1248
if is_new_repo and revision_id is not None and not is_stacked:
1249
fetch_spec = graph.PendingAncestryResult(
1250
[revision_id], source_repository)
1253
if source_repository is not None:
1254
# Fetch while stacked to prevent unstacked fetch from
1256
if fetch_spec is None:
1257
result_repo.fetch(source_repository, revision_id=revision_id)
1259
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
1261
if source_branch is None:
1262
# this is for sprouting a bzrdir without a branch; is that
1264
# Not especially, but it's part of the contract.
1265
result_branch = result.create_branch()
1267
result_branch = source_branch.sprout(result,
1268
revision_id=revision_id, repository_policy=repository_policy)
1269
mutter("created new branch %r" % (result_branch,))
1271
# Create/update the result working tree
1272
if (create_tree_if_local and
1273
isinstance(target_transport, local.LocalTransport) and
1274
(result_repo is None or result_repo.make_working_trees())):
1275
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
1279
if wt.path2id('') is None:
1281
wt.set_root_id(self.open_workingtree.get_root_id())
1282
except errors.NoWorkingTree:
1288
if recurse == 'down':
1290
basis = wt.basis_tree()
1292
subtrees = basis.iter_references()
1293
elif result_branch is not None:
1294
basis = result_branch.basis_tree()
1296
subtrees = basis.iter_references()
1297
elif source_branch is not None:
1298
basis = source_branch.basis_tree()
1300
subtrees = basis.iter_references()
1305
for path, file_id in subtrees:
1306
target = urlutils.join(url, urlutils.escape(path))
1307
sublocation = source_branch.reference_parent(file_id, path)
1308
sublocation.bzrdir.sprout(target,
1309
basis.get_reference_revision(file_id, path),
1310
force_new_repo=force_new_repo, recurse=recurse,
1313
if basis is not None:
1317
def push_branch(self, source, revision_id=None, overwrite=False,
1318
remember=False, create_prefix=False):
1319
"""Push the source branch into this BzrDir."""
1321
# If we can open a branch, use its direct repository, otherwise see
1322
# if there is a repository without a branch.
1324
br_to = self.open_branch()
1325
except errors.NotBranchError:
1326
# Didn't find a branch, can we find a repository?
1327
repository_to = self.find_repository()
1329
# Found a branch, so we must have found a repository
1330
repository_to = br_to.repository
1332
push_result = PushResult()
1333
push_result.source_branch = source
1335
# We have a repository but no branch, copy the revisions, and then
1337
repository_to.fetch(source.repository, revision_id=revision_id)
1338
br_to = source.clone(self, revision_id=revision_id)
1339
if source.get_push_location() is None or remember:
1340
source.set_push_location(br_to.base)
1341
push_result.stacked_on = None
1342
push_result.branch_push_result = None
1343
push_result.old_revno = None
1344
push_result.old_revid = _mod_revision.NULL_REVISION
1345
push_result.target_branch = br_to
1346
push_result.master_branch = None
1347
push_result.workingtree_updated = False
1349
# We have successfully opened the branch, remember if necessary:
1350
if source.get_push_location() is None or remember:
1351
source.set_push_location(br_to.base)
1353
tree_to = self.open_workingtree()
1354
except errors.NotLocalUrl:
1355
push_result.branch_push_result = source.push(br_to,
1356
overwrite, stop_revision=revision_id)
1357
push_result.workingtree_updated = False
1358
except errors.NoWorkingTree:
1359
push_result.branch_push_result = source.push(br_to,
1360
overwrite, stop_revision=revision_id)
1361
push_result.workingtree_updated = None # Not applicable
1363
tree_to.lock_write()
1365
push_result.branch_push_result = source.push(
1366
tree_to.branch, overwrite, stop_revision=revision_id)
1370
push_result.workingtree_updated = True
1371
push_result.old_revno = push_result.branch_push_result.old_revno
1372
push_result.old_revid = push_result.branch_push_result.old_revid
1373
push_result.target_branch = \
1374
push_result.branch_push_result.target_branch
1378
1001
class BzrDirHooks(hooks.Hooks):
1379
1002
"""Hooks for BzrDir operations."""