86
def _get_branch_location(control_dir, possible_transports=None):
87
"""Return location of branch for this control dir."""
89
this_branch = control_dir.open_branch(
90
possible_transports=possible_transports)
91
# This may be a heavy checkout, where we want the master branch
92
master_location = this_branch.get_bound_location()
93
if master_location is not None:
94
return master_location
95
# If not, use a local sibling
96
return this_branch.base
97
except errors.NotBranchError:
98
format = control_dir.find_branch_format()
99
if getattr(format, 'get_reference', None) is not None:
100
return format.get_reference(control_dir)
102
return control_dir.root_transport.base
105
def _is_colocated(control_dir, possible_transports=None):
106
"""Check if the branch in control_dir is colocated.
108
:param control_dir: Control directory
109
:return: Boolean indicating whether
111
# This path is meant to be relative to the existing branch
112
this_url = _get_branch_location(control_dir,
113
possible_transports=possible_transports)
114
# Perhaps the target control dir supports colocated branches?
116
root = controldir.ControlDir.open(this_url,
117
possible_transports=possible_transports)
118
except errors.NotBranchError:
119
return (False, this_url)
122
wt = control_dir.open_workingtree()
123
except (errors.NoWorkingTree, errors.NotLocalUrl):
124
return (False, this_url)
127
root._format.colocated_branches and
128
control_dir.control_url == root.control_url,
132
def lookup_new_sibling_branch(control_dir, location, possible_transports=None):
133
"""Lookup the location for a new sibling branch.
135
:param control_dir: Control directory relative to which to look up
137
:param location: Name of the new branch
138
:return: Full location to the new branch
140
location = directory_service.directories.dereference(location)
141
if '/' not in location and '\\' not in location:
142
(colocated, this_url) = _is_colocated(control_dir, possible_transports)
145
return urlutils.join_segment_parameters(this_url,
146
{"branch": urlutils.escape(location)})
148
return urlutils.join(this_url, '..', urlutils.escape(location))
152
def lookup_sibling_branch(control_dir, location, possible_transports=None):
153
"""Lookup sibling branch.
155
:param control_dir: Control directory relative to which to lookup the
157
:param location: Location to look up
158
:return: branch to open
161
# Perhaps it's a colocated branch?
162
return control_dir.open_branch(location,
163
possible_transports=possible_transports)
164
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
166
return Branch.open(location)
167
except errors.NotBranchError:
168
this_url = _get_branch_location(control_dir)
171
this_url, '..', urlutils.escape(location)))
83
174
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
84
175
def tree_files(file_list, default_branch=u'.', canonicalize=True,
755
846
takes_args = ['dir+']
850
help='No error if existing, make parent directories as needed.',
756
854
encoding_type = 'replace'
758
def run(self, dir_list):
760
wt, dd = WorkingTree.open_containing(d)
761
base = os.path.dirname(dd)
762
id = wt.path2id(base)
767
self.outf.write(gettext('added %s\n') % d)
857
def add_file_with_parents(cls, wt, relpath):
858
if wt.path2id(relpath) is not None:
860
cls.add_file_with_parents(wt, osutils.dirname(relpath))
864
def add_file_single(cls, wt, relpath):
867
def run(self, dir_list, parents=False):
869
add_file = self.add_file_with_parents
871
add_file = self.add_file_single
873
wt, relpath = WorkingTree.open_containing(dir)
878
if e.errno != errno.EEXIST:
769
raise errors.NotVersionedError(path=base)
882
add_file(wt, relpath)
884
self.outf.write(gettext('added %s\n') % dir)
772
887
class cmd_relpath(Command):
940
self.add_cleanup(tree.lock_read().unlock)
825
941
if file_list is not None:
826
942
file_ids = tree.paths2ids(file_list, trees=extra_trees,
827
943
require_versioned=True)
828
944
# find_ids_across_trees may include some paths that don't
829
945
# exist in 'tree'.
831
(tree.id2path(file_id), tree.inventory[file_id])
832
for file_id in file_ids if tree.has_id(file_id))
946
entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
834
entries = tree.inventory.entries()
948
entries = tree.iter_entries_by_dir()
837
for path, entry in entries:
950
for path, entry in sorted(entries):
838
951
if kind and kind != entry.kind:
841
956
self.outf.write('%-50s %s\n' % (path, entry.file_id))
1221
1340
if location is None:
1222
1341
stored_loc = br_from.get_push_location()
1223
1342
if stored_loc is None:
1224
raise errors.BzrCommandError(gettext(
1225
"No push location known or specified."))
1343
parent_loc = br_from.get_parent()
1345
raise errors.BzrCommandError(gettext(
1346
"No push location known or specified. To push to the "
1347
"parent branch (at %s), use 'bzr push :parent'." %
1348
urlutils.unescape_for_display(parent_loc,
1349
self.outf.encoding)))
1351
raise errors.BzrCommandError(gettext(
1352
"No push location known or specified."))
1227
1354
display_url = urlutils.unescape_for_display(stored_loc,
1228
1355
self.outf.encoding)
1310
1437
revision_id = br_from.last_revision()
1311
1438
if to_location is None:
1312
to_location = urlutils.derive_to_location(from_location)
1439
to_location = getattr(br_from, "name", None)
1441
to_location = urlutils.derive_to_location(from_location)
1313
1442
to_transport = transport.get_transport(to_location)
1315
1444
to_transport.mkdir('.')
1316
1445
except errors.FileExists:
1317
if not use_existing_dir:
1318
raise errors.BzrCommandError(gettext('Target directory "%s" '
1319
'already exists.') % to_location)
1322
to_dir = controldir.ControlDir.open_from_transport(
1324
except errors.NotBranchError:
1447
to_dir = controldir.ControlDir.open_from_transport(
1449
except errors.NotBranchError:
1450
if not use_existing_dir:
1451
raise errors.BzrCommandError(gettext('Target directory "%s" '
1452
'already exists.') % to_location)
1457
to_dir.open_branch()
1458
except errors.NotBranchError:
1328
to_dir.open_branch()
1329
except errors.NotBranchError:
1332
raise errors.AlreadyBranchError(to_location)
1461
raise errors.AlreadyBranchError(to_location)
1333
1462
except errors.NoSuchFile:
1334
1463
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1345
1474
force_new_repo=standalone,
1346
1475
create_tree_if_local=not no_tree,
1347
1476
source_branch=br_from)
1348
branch = to_dir.open_branch()
1477
branch = to_dir.open_branch(
1478
possible_transports=[
1479
br_from.bzrdir.root_transport, to_transport])
1349
1480
except errors.NoSuchRevision:
1350
1481
to_transport.delete_tree('.')
1351
1482
msg = gettext("The branch {0} has no revision {1}.").format(
1352
1483
from_location, revision)
1353
1484
raise errors.BzrCommandError(msg)
1487
to_repo = to_dir.open_repository()
1488
except errors.NoRepositoryPresent:
1489
to_repo = to_dir.create_repository()
1490
to_repo.fetch(br_from.repository, revision_id=revision_id)
1355
1491
branch = br_from.sprout(to_dir, revision_id=revision_id)
1356
1492
_merge_tags_if_possible(br_from, branch)
1357
1493
# If the source branch is stacked, the new branch may
1401
1537
self.outf.encoding).rstrip("/"))
1403
1539
dir = controldir.ControlDir.open_containing(location)[0]
1404
for branch in dir.list_branches():
1405
if branch.name is None:
1406
self.outf.write(gettext(" (default)\n"))
1541
active_branch = dir.open_branch(name="")
1542
except errors.NotBranchError:
1543
active_branch = None
1544
branches = dir.get_branches()
1546
for name, branch in branches.iteritems():
1549
active = (active_branch is not None and
1550
active_branch.base == branch.base)
1551
names[name] = active
1552
# Only mention the current branch explicitly if it's not
1553
# one of the colocated branches
1554
if not any(names.values()) and active_branch is not None:
1555
self.outf.write("* %s\n" % gettext("(default)"))
1556
for name in sorted(names.keys()):
1557
active = names[name]
1408
self.outf.write(" %s\n" % branch.name.encode(
1409
self.outf.encoding))
1562
self.outf.write("%s %s\n" % (
1563
prefix, name.encode(self.outf.encoding)))
1412
1566
class cmd_checkout(Command):
1496
1650
def run(self, dir=u'.'):
1497
1651
tree = WorkingTree.open_containing(dir)[0]
1498
1652
self.add_cleanup(tree.lock_read().unlock)
1499
new_inv = tree.inventory
1653
new_inv = tree.root_inventory
1500
1654
old_tree = tree.basis_tree()
1501
1655
self.add_cleanup(old_tree.lock_read().unlock)
1502
old_inv = old_tree.inventory
1656
old_inv = old_tree.root_inventory
1504
1658
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1505
1659
for f, paths, c, v, p, n, k, e in iterator:
2028
2182
to_transport = transport.get_transport(location)
2029
to_transport.ensure_base()
2031
newdir = format.initialize_on_transport(to_transport)
2032
repo = newdir.create_repository(shared=True)
2033
repo.set_make_working_trees(not no_trees)
2184
(repo, newdir, require_stacking, repository_policy) = (
2185
format.initialize_on_transport_ex(to_transport,
2186
create_prefix=True, make_working_trees=not no_trees,
2187
shared_repo=True, force_new_repo=True,
2188
use_existing_dir=True,
2189
repo_format_name=format.repository_format.get_format_string()))
2034
2190
if not is_quiet():
2035
2191
from bzrlib.info import show_bzrdir_info
2036
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
2192
show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
2039
2195
class cmd_diff(Command):
2261
2417
self.add_cleanup(wt.lock_read().unlock)
2262
2418
basis = wt.basis_tree()
2263
2419
self.add_cleanup(basis.lock_read().unlock)
2264
basis_inv = basis.inventory
2267
if basis_inv.has_id(file_id):
2269
if inv.is_root(file_id) and len(basis_inv) == 0:
2271
path = inv.id2path(file_id)
2420
root_id = wt.get_root_id()
2421
for file_id in wt.all_file_ids():
2422
if basis.has_id(file_id):
2424
if root_id == file_id:
2426
path = wt.id2path(file_id)
2272
2427
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
3141
3296
Option('per-file-timestamps',
3142
3297
help='Set modification time of files to that of the last '
3143
3298
'revision in which it was changed.'),
3299
Option('uncommitted',
3300
help='Export the working tree contents rather than that of the '
3145
3303
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3146
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
3304
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
3147
3306
from bzrlib.export import export
3149
3308
if branch_or_subdir is None:
3150
tree = WorkingTree.open_containing(directory)[0]
3309
branch_or_subdir = directory
3311
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3313
if tree is not None:
3314
self.add_cleanup(tree.lock_read().unlock)
3318
raise errors.BzrCommandError(
3319
gettext("--uncommitted requires a working tree"))
3154
b, subdir = Branch.open_containing(branch_or_subdir)
3157
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3322
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3159
export(rev_tree, dest, format, root, subdir, filtered=filters,
3324
export(export_tree, dest, format, root, subdir, filtered=filters,
3160
3325
per_file_timestamps=per_file_timestamps)
3161
3326
except errors.NoSuchExportFormat, e:
3162
raise errors.BzrCommandError(gettext('Unsupported export format: %s') % e.format)
3327
raise errors.BzrCommandError(
3328
gettext('Unsupported export format: %s') % e.format)
3165
3331
class cmd_cat(Command):
3668
3834
if directory is None:
3669
3835
# use branch if we're inside one; otherwise global config
3671
c = Branch.open_containing(u'.')[0].get_config()
3837
c = Branch.open_containing(u'.')[0].get_config_stack()
3672
3838
except errors.NotBranchError:
3673
c = _mod_config.GlobalConfig()
3839
c = _mod_config.GlobalStack()
3675
c = Branch.open(directory).get_config()
3841
c = Branch.open(directory).get_config_stack()
3842
identity = c.get('email')
3677
self.outf.write(c.user_email() + '\n')
3844
self.outf.write(_mod_config.extract_email_address(identity)
3679
self.outf.write(c.username() + '\n')
3847
self.outf.write(identity + '\n')
3693
3861
# use global config unless --branch given
3695
3863
if directory is None:
3696
c = Branch.open_containing(u'.')[0].get_config()
3864
c = Branch.open_containing(u'.')[0].get_config_stack()
3698
c = Branch.open(directory).get_config()
3866
b = Branch.open(directory)
3867
self.add_cleanup(b.lock_write().unlock)
3868
c = b.get_config_stack()
3700
c = _mod_config.GlobalConfig()
3701
c.set_user_option('email', name)
3870
c = _mod_config.GlobalStack()
3871
c.set('email', name)
3704
3874
class cmd_nick(Command):
3705
3875
__doc__ = """Print or set the branch nickname.
3707
If unset, the tree root directory name is used as the nickname.
3708
To print the current nickname, execute with no argument.
3877
If unset, the colocated branch name is used for colocated branches, and
3878
the branch directory name is used for other branches. To print the
3879
current nickname, execute with no argument.
3710
3881
Bound branches use the nickname of its master branch unless it is set
3929
4100
load_list=None, debugflag=None, starting_with=None, subunit=False,
3930
4101
parallel=None, lsprof_tests=False,
4104
# During selftest, disallow proxying, as it can cause severe
4105
# performance penalties and is only needed for thread
4106
# safety. The selftest command is assumed to not use threads
4107
# too heavily. The call should be as early as possible, as
4108
# error reporting for past duplicate imports won't have useful
4110
lazy_import.disallow_proxying()
3932
4112
from bzrlib import tests
3934
4114
if testspecs_list is not None:
5086
5267
if location is None:
5087
5268
if b.get_bound_location() is not None:
5088
raise errors.BzrCommandError(gettext('Branch is already bound'))
5269
raise errors.BzrCommandError(
5270
gettext('Branch is already bound'))
5090
raise errors.BzrCommandError(gettext('No location supplied '
5091
'and no previous location known'))
5272
raise errors.BzrCommandError(
5273
gettext('No location supplied'
5274
' and no previous location known'))
5092
5275
b_other = Branch.open(location)
5094
5277
b.bind(b_other)
6044
6228
from bzrlib import switch
6045
6229
tree_location = directory
6046
6230
revision = _get_one_revision('switch', revision)
6047
control_dir = controldir.ControlDir.open_containing(tree_location)[0]
6231
possible_transports = []
6232
control_dir = controldir.ControlDir.open_containing(tree_location,
6233
possible_transports=possible_transports)[0]
6048
6234
if to_location is None:
6049
6235
if revision is None:
6050
6236
raise errors.BzrCommandError(gettext('You must supply either a'
6051
6237
' revision or a location'))
6052
6238
to_location = tree_location
6054
branch = control_dir.open_branch()
6240
branch = control_dir.open_branch(
6241
possible_transports=possible_transports)
6055
6242
had_explicit_nick = branch.get_config().has_explicit_nickname()
6056
6243
except errors.NotBranchError:
6058
6245
had_explicit_nick = False
6059
6246
if create_branch:
6060
6247
if branch is None:
6061
raise errors.BzrCommandError(gettext('cannot create branch without'
6063
to_location = directory_service.directories.dereference(
6065
if '/' not in to_location and '\\' not in to_location:
6066
# This path is meant to be relative to the existing branch
6067
this_url = self._get_branch_location(control_dir)
6068
to_location = urlutils.join(this_url, '..', to_location)
6248
raise errors.BzrCommandError(
6249
gettext('cannot create branch without source branch'))
6250
to_location = lookup_new_sibling_branch(control_dir, to_location,
6251
possible_transports=possible_transports)
6069
6252
to_branch = branch.bzrdir.sprout(to_location,
6070
possible_transports=[branch.bzrdir.root_transport],
6071
source_branch=branch).open_branch()
6253
possible_transports=possible_transports,
6254
source_branch=branch).open_branch()
6074
to_branch = Branch.open(to_location)
6075
except errors.NotBranchError:
6076
this_url = self._get_branch_location(control_dir)
6077
to_branch = Branch.open(
6078
urlutils.join(this_url, '..', to_location))
6256
to_branch = lookup_sibling_branch(control_dir, to_location)
6079
6257
if revision is not None:
6080
6258
revision = revision.as_revision_id(to_branch)
6081
6259
switch.switch(control_dir, to_branch, force, revision_id=revision)
6085
6263
note(gettext('Switched to branch: %s'),
6086
6264
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6088
def _get_branch_location(self, control_dir):
6089
"""Return location of branch for this control dir."""
6091
this_branch = control_dir.open_branch()
6092
# This may be a heavy checkout, where we want the master branch
6093
master_location = this_branch.get_bound_location()
6094
if master_location is not None:
6095
return master_location
6096
# If not, use a local sibling
6097
return this_branch.base
6098
except errors.NotBranchError:
6099
format = control_dir.find_branch_format()
6100
if getattr(format, 'get_reference', None) is not None:
6101
return format.get_reference(control_dir)
6103
return control_dir.root_transport.base
6106
6268
class cmd_view(Command):
6514
6676
takes_options = [Option('plugin',
6515
6677
help='Export help text from named command '\
6516
6678
'(defaults to all built in commands).',
6680
Option('include-duplicates',
6681
help='Output multiple copies of the same msgid '
6682
'string if it appears more than once.'),
6519
def run(self, plugin=None):
6685
def run(self, plugin=None, include_duplicates=False):
6520
6686
from bzrlib.export_pot import export_pot
6521
export_pot(self.outf, plugin)
6687
export_pot(self.outf, plugin, include_duplicates)
6524
6690
def _register_lazy_builtins():