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)))
174
83
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
175
84
def tree_files(file_list, default_branch=u'.', canonicalize=True,
846
755
takes_args = ['dir+']
850
help='No error if existing, make parent directories as needed.',
854
756
encoding_type = 'replace'
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:
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)
882
add_file(wt, relpath)
884
self.outf.write(gettext('added %s\n') % dir)
769
raise errors.NotVersionedError(path=base)
887
772
class cmd_relpath(Command):
940
self.add_cleanup(tree.lock_read().unlock)
941
825
if file_list is not None:
942
826
file_ids = tree.paths2ids(file_list, trees=extra_trees,
943
827
require_versioned=True)
944
828
# find_ids_across_trees may include some paths that don't
945
829
# exist in 'tree'.
946
entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
831
(tree.id2path(file_id), tree.inventory[file_id])
832
for file_id in file_ids if tree.has_id(file_id))
948
entries = tree.iter_entries_by_dir()
834
entries = tree.inventory.entries()
950
for path, entry in sorted(entries):
837
for path, entry in entries:
951
838
if kind and kind != entry.kind:
956
841
self.outf.write('%-50s %s\n' % (path, entry.file_id))
1340
1224
if location is None:
1341
1225
stored_loc = br_from.get_push_location()
1342
1226
if stored_loc is None:
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
raise errors.BzrCommandError(gettext(
1228
"No push location known or specified."))
1354
1230
display_url = urlutils.unescape_for_display(stored_loc,
1355
1231
self.outf.encoding)
1437
1313
revision_id = br_from.last_revision()
1438
1314
if to_location is None:
1439
to_location = getattr(br_from, "name", None)
1441
to_location = urlutils.derive_to_location(from_location)
1315
to_location = urlutils.derive_to_location(from_location)
1442
1316
to_transport = transport.get_transport(to_location)
1444
1318
to_transport.mkdir('.')
1445
1319
except errors.FileExists:
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)
1320
if not use_existing_dir:
1321
raise errors.BzrCommandError(gettext('Target directory "%s" '
1322
'already exists.') % to_location)
1325
to_dir = controldir.ControlDir.open_from_transport(
1327
except errors.NotBranchError:
1457
to_dir.open_branch()
1458
except errors.NotBranchError:
1461
raise errors.AlreadyBranchError(to_location)
1331
to_dir.open_branch()
1332
except errors.NotBranchError:
1335
raise errors.AlreadyBranchError(to_location)
1462
1336
except errors.NoSuchFile:
1463
1337
raise errors.BzrCommandError(gettext('Parent of "%s" does not exist.')
1474
1348
force_new_repo=standalone,
1475
1349
create_tree_if_local=not no_tree,
1476
1350
source_branch=br_from)
1477
branch = to_dir.open_branch(
1478
possible_transports=[
1479
br_from.bzrdir.root_transport, to_transport])
1351
branch = to_dir.open_branch()
1480
1352
except errors.NoSuchRevision:
1481
1353
to_transport.delete_tree('.')
1482
1354
msg = gettext("The branch {0} has no revision {1}.").format(
1483
1355
from_location, revision)
1484
1356
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)
1491
1358
branch = br_from.sprout(to_dir, revision_id=revision_id)
1492
1359
_merge_tags_if_possible(br_from, branch)
1493
1360
# If the source branch is stacked, the new branch may
1537
1404
self.outf.encoding).rstrip("/"))
1539
1406
dir = controldir.ControlDir.open_containing(location)[0]
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]
1407
for branch in dir.list_branches():
1408
if branch.name is None:
1409
self.outf.write(gettext(" (default)\n"))
1562
self.outf.write("%s %s\n" % (
1563
prefix, name.encode(self.outf.encoding)))
1411
self.outf.write(" %s\n" % branch.name.encode(
1412
self.outf.encoding))
1566
1415
class cmd_checkout(Command):
1650
1499
def run(self, dir=u'.'):
1651
1500
tree = WorkingTree.open_containing(dir)[0]
1652
1501
self.add_cleanup(tree.lock_read().unlock)
1502
new_inv = tree.inventory
1653
1503
old_tree = tree.basis_tree()
1654
1504
self.add_cleanup(old_tree.lock_read().unlock)
1505
old_inv = old_tree.inventory
1656
1507
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1657
1508
for f, paths, c, v, p, n, k, e in iterator:
2180
2031
to_transport = transport.get_transport(location)
2032
to_transport.ensure_base()
2182
(repo, newdir, require_stacking, repository_policy) = (
2183
format.initialize_on_transport_ex(to_transport,
2184
create_prefix=True, make_working_trees=not no_trees,
2185
shared_repo=True, force_new_repo=True,
2186
use_existing_dir=True,
2187
repo_format_name=format.repository_format.get_format_string()))
2034
newdir = format.initialize_on_transport(to_transport)
2035
repo = newdir.create_repository(shared=True)
2036
repo.set_make_working_trees(not no_trees)
2188
2037
if not is_quiet():
2189
2038
from bzrlib.info import show_bzrdir_info
2190
show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
2039
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
2193
2042
class cmd_diff(Command):
2415
2264
self.add_cleanup(wt.lock_read().unlock)
2416
2265
basis = wt.basis_tree()
2417
2266
self.add_cleanup(basis.lock_read().unlock)
2418
root_id = wt.get_root_id()
2419
for file_id in wt.all_file_ids():
2420
if basis.has_id(file_id):
2422
if root_id == file_id:
2424
path = wt.id2path(file_id)
2267
basis_inv = basis.inventory
2270
if basis_inv.has_id(file_id):
2272
if inv.is_root(file_id) and len(basis_inv) == 0:
2274
path = inv.id2path(file_id)
2425
2275
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
3294
3144
Option('per-file-timestamps',
3295
3145
help='Set modification time of files to that of the last '
3296
3146
'revision in which it was changed.'),
3297
Option('uncommitted',
3298
help='Export the working tree contents rather than that of the '
3301
3148
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3302
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
3149
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
3304
3150
from bzrlib.export import export
3306
3152
if branch_or_subdir is None:
3307
branch_or_subdir = directory
3309
(tree, b, subdir) = controldir.ControlDir.open_containing_tree_or_branch(
3311
if tree is not None:
3312
self.add_cleanup(tree.lock_read().unlock)
3316
raise errors.BzrCommandError(
3317
gettext("--uncommitted requires a working tree"))
3153
tree = WorkingTree.open_containing(directory)[0]
3320
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3157
b, subdir = Branch.open_containing(branch_or_subdir)
3160
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3322
export(export_tree, dest, format, root, subdir, filtered=filters,
3162
export(rev_tree, dest, format, root, subdir, filtered=filters,
3323
3163
per_file_timestamps=per_file_timestamps)
3324
3164
except errors.NoSuchExportFormat, e:
3325
raise errors.BzrCommandError(
3326
gettext('Unsupported export format: %s') % e.format)
3165
raise errors.BzrCommandError(gettext('Unsupported export format: %s') % e.format)
3329
3168
class cmd_cat(Command):
3832
3671
if directory is None:
3833
3672
# use branch if we're inside one; otherwise global config
3835
c = Branch.open_containing(u'.')[0].get_config_stack()
3674
c = Branch.open_containing(u'.')[0].get_config()
3836
3675
except errors.NotBranchError:
3837
c = _mod_config.GlobalStack()
3676
c = _mod_config.GlobalConfig()
3839
c = Branch.open(directory).get_config_stack()
3840
identity = c.get('email')
3678
c = Branch.open(directory).get_config()
3842
self.outf.write(_mod_config.extract_email_address(identity)
3680
self.outf.write(c.user_email() + '\n')
3845
self.outf.write(identity + '\n')
3682
self.outf.write(c.username() + '\n')
3859
3696
# use global config unless --branch given
3861
3698
if directory is None:
3862
c = Branch.open_containing(u'.')[0].get_config_stack()
3699
c = Branch.open_containing(u'.')[0].get_config()
3864
b = Branch.open(directory)
3865
self.add_cleanup(b.lock_write().unlock)
3866
c = b.get_config_stack()
3701
c = Branch.open(directory).get_config()
3868
c = _mod_config.GlobalStack()
3869
c.set('email', name)
3703
c = _mod_config.GlobalConfig()
3704
c.set_user_option('email', name)
3872
3707
class cmd_nick(Command):
3873
3708
__doc__ = """Print or set the branch nickname.
3875
If unset, the colocated branch name is used for colocated branches, and
3876
the branch directory name is used for other branches. To print the
3877
current nickname, execute with no argument.
3710
If unset, the tree root directory name is used as the nickname.
3711
To print the current nickname, execute with no argument.
3879
3713
Bound branches use the nickname of its master branch unless it is set
4098
3932
load_list=None, debugflag=None, starting_with=None, subunit=False,
4099
3933
parallel=None, lsprof_tests=False,
4102
# During selftest, disallow proxying, as it can cause severe
4103
# performance penalties and is only needed for thread
4104
# safety. The selftest command is assumed to not use threads
4105
# too heavily. The call should be as early as possible, as
4106
# error reporting for past duplicate imports won't have useful
4108
lazy_import.disallow_proxying()
4110
3935
from bzrlib import tests
4112
3937
if testspecs_list is not None:
5265
5089
if location is None:
5266
5090
if b.get_bound_location() is not None:
5267
raise errors.BzrCommandError(
5268
gettext('Branch is already bound'))
5091
raise errors.BzrCommandError(gettext('Branch is already bound'))
5270
raise errors.BzrCommandError(
5271
gettext('No location supplied'
5272
' and no previous location known'))
5093
raise errors.BzrCommandError(gettext('No location supplied '
5094
'and no previous location known'))
5273
5095
b_other = Branch.open(location)
5275
5097
b.bind(b_other)
6226
6047
from bzrlib import switch
6227
6048
tree_location = directory
6228
6049
revision = _get_one_revision('switch', revision)
6229
possible_transports = []
6230
control_dir = controldir.ControlDir.open_containing(tree_location,
6231
possible_transports=possible_transports)[0]
6050
control_dir = controldir.ControlDir.open_containing(tree_location)[0]
6232
6051
if to_location is None:
6233
6052
if revision is None:
6234
6053
raise errors.BzrCommandError(gettext('You must supply either a'
6235
6054
' revision or a location'))
6236
6055
to_location = tree_location
6238
branch = control_dir.open_branch(
6239
possible_transports=possible_transports)
6057
branch = control_dir.open_branch()
6240
6058
had_explicit_nick = branch.get_config().has_explicit_nickname()
6241
6059
except errors.NotBranchError:
6243
6061
had_explicit_nick = False
6244
6062
if create_branch:
6245
6063
if branch is None:
6246
raise errors.BzrCommandError(
6247
gettext('cannot create branch without source branch'))
6248
to_location = lookup_new_sibling_branch(control_dir, to_location,
6249
possible_transports=possible_transports)
6064
raise errors.BzrCommandError(gettext('cannot create branch without'
6066
to_location = directory_service.directories.dereference(
6068
if '/' not in to_location and '\\' not in to_location:
6069
# This path is meant to be relative to the existing branch
6070
this_url = self._get_branch_location(control_dir)
6071
to_location = urlutils.join(this_url, '..', to_location)
6250
6072
to_branch = branch.bzrdir.sprout(to_location,
6251
possible_transports=possible_transports,
6252
source_branch=branch).open_branch()
6073
possible_transports=[branch.bzrdir.root_transport],
6074
source_branch=branch).open_branch()
6254
to_branch = lookup_sibling_branch(control_dir, to_location)
6077
to_branch = Branch.open(to_location)
6078
except errors.NotBranchError:
6079
this_url = self._get_branch_location(control_dir)
6080
to_branch = Branch.open(
6081
urlutils.join(this_url, '..', to_location))
6255
6082
if revision is not None:
6256
6083
revision = revision.as_revision_id(to_branch)
6257
6084
switch.switch(control_dir, to_branch, force, revision_id=revision)
6261
6088
note(gettext('Switched to branch: %s'),
6262
6089
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6091
def _get_branch_location(self, control_dir):
6092
"""Return location of branch for this control dir."""
6094
this_branch = control_dir.open_branch()
6095
# This may be a heavy checkout, where we want the master branch
6096
master_location = this_branch.get_bound_location()
6097
if master_location is not None:
6098
return master_location
6099
# If not, use a local sibling
6100
return this_branch.base
6101
except errors.NotBranchError:
6102
format = control_dir.find_branch_format()
6103
if getattr(format, 'get_reference', None) is not None:
6104
return format.get_reference(control_dir)
6106
return control_dir.root_transport.base
6266
6109
class cmd_view(Command):
6674
6517
takes_options = [Option('plugin',
6675
6518
help='Export help text from named command '\
6676
6519
'(defaults to all built in commands).',
6678
Option('include-duplicates',
6679
help='Output multiple copies of the same msgid '
6680
'string if it appears more than once.'),
6683
def run(self, plugin=None, include_duplicates=False):
6522
def run(self, plugin=None):
6684
6523
from bzrlib.export_pot import export_pot
6685
export_pot(self.outf, plugin, include_duplicates)
6524
export_pot(self.outf, plugin)
6688
6527
def _register_lazy_builtins():