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)
1476
1352
source_branch=br_from)
1477
1353
branch = to_dir.open_branch(
1478
1354
possible_transports=[
1479
br_from.bzrdir.root_transport, to_transport])
1355
br_from.control_transport, to_transport])
1480
1356
except errors.NoSuchRevision:
1481
1357
to_transport.delete_tree('.')
1482
1358
msg = gettext("The branch {0} has no revision {1}.").format(
1483
1359
from_location, revision)
1484
1360
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
1362
branch = br_from.sprout(to_dir, revision_id=revision_id)
1492
1363
_merge_tags_if_possible(br_from, branch)
1493
1364
# If the source branch is stacked, the new branch may
1537
1408
self.outf.encoding).rstrip("/"))
1539
1410
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]
1411
for branch in dir.list_branches():
1412
if branch.name is None:
1413
self.outf.write(gettext(" (default)\n"))
1562
self.outf.write("%s %s\n" % (
1563
prefix, name.encode(self.outf.encoding)))
1415
self.outf.write(" %s\n" % branch.name.encode(
1416
self.outf.encoding))
1566
1419
class cmd_checkout(Command):
1650
1503
def run(self, dir=u'.'):
1651
1504
tree = WorkingTree.open_containing(dir)[0]
1652
1505
self.add_cleanup(tree.lock_read().unlock)
1506
new_inv = tree.inventory
1653
1507
old_tree = tree.basis_tree()
1654
1508
self.add_cleanup(old_tree.lock_read().unlock)
1509
old_inv = old_tree.inventory
1656
1511
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1657
1512
for f, paths, c, v, p, n, k, e in iterator:
2180
2035
to_transport = transport.get_transport(location)
2036
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()))
2038
newdir = format.initialize_on_transport(to_transport)
2039
repo = newdir.create_repository(shared=True)
2040
repo.set_make_working_trees(not no_trees)
2188
2041
if not is_quiet():
2189
2042
from bzrlib.info import show_bzrdir_info
2190
show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
2043
show_bzrdir_info(repo.bzrdir, verbose=0, outfile=self.outf)
2193
2046
class cmd_diff(Command):
2415
2268
self.add_cleanup(wt.lock_read().unlock)
2416
2269
basis = wt.basis_tree()
2417
2270
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)
2271
basis_inv = basis.inventory
2274
if basis_inv.has_id(file_id):
2276
if inv.is_root(file_id) and len(basis_inv) == 0:
2278
path = inv.id2path(file_id)
2425
2279
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
3294
3148
Option('per-file-timestamps',
3295
3149
help='Set modification time of files to that of the last '
3296
3150
'revision in which it was changed.'),
3297
Option('uncommitted',
3298
help='Export the working tree contents rather than that of the '
3301
3152
def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3302
root=None, filters=False, per_file_timestamps=False, uncommitted=False,
3153
root=None, filters=False, per_file_timestamps=False, directory=u'.'):
3304
3154
from bzrlib.export import export
3306
3156
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"))
3157
tree = WorkingTree.open_containing(directory)[0]
3320
export_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3161
b, subdir = Branch.open_containing(branch_or_subdir)
3164
rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
3322
export(export_tree, dest, format, root, subdir, filtered=filters,
3166
export(rev_tree, dest, format, root, subdir, filtered=filters,
3323
3167
per_file_timestamps=per_file_timestamps)
3324
3168
except errors.NoSuchExportFormat, e:
3325
raise errors.BzrCommandError(
3326
gettext('Unsupported export format: %s') % e.format)
3169
raise errors.BzrCommandError(gettext('Unsupported export format: %s') % e.format)
3329
3172
class cmd_cat(Command):
3832
3675
if directory is None:
3833
3676
# use branch if we're inside one; otherwise global config
3835
c = Branch.open_containing(u'.')[0].get_config_stack()
3678
c = Branch.open_containing(u'.')[0].get_config()
3836
3679
except errors.NotBranchError:
3837
c = _mod_config.GlobalStack()
3680
c = _mod_config.GlobalConfig()
3839
c = Branch.open(directory).get_config_stack()
3840
identity = c.get('email')
3682
c = Branch.open(directory).get_config()
3842
self.outf.write(_mod_config.extract_email_address(identity)
3684
self.outf.write(c.user_email() + '\n')
3845
self.outf.write(identity + '\n')
3686
self.outf.write(c.username() + '\n')
3859
3700
# use global config unless --branch given
3861
3702
if directory is None:
3862
c = Branch.open_containing(u'.')[0].get_config_stack()
3703
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()
3705
c = Branch.open(directory).get_config()
3868
c = _mod_config.GlobalStack()
3869
c.set('email', name)
3707
c = _mod_config.GlobalConfig()
3708
c.set_user_option('email', name)
3872
3711
class cmd_nick(Command):
3873
3712
__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.
3714
If unset, the tree root directory name is used as the nickname.
3715
To print the current nickname, execute with no argument.
3879
3717
Bound branches use the nickname of its master branch unless it is set
4098
3936
load_list=None, debugflag=None, starting_with=None, subunit=False,
4099
3937
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
3939
from bzrlib import tests
4112
3941
if testspecs_list is not None:
5265
5093
if location is None:
5266
5094
if b.get_bound_location() is not None:
5267
raise errors.BzrCommandError(
5268
gettext('Branch is already bound'))
5095
raise errors.BzrCommandError(gettext('Branch is already bound'))
5270
raise errors.BzrCommandError(
5271
gettext('No location supplied'
5272
' and no previous location known'))
5097
raise errors.BzrCommandError(gettext('No location supplied '
5098
'and no previous location known'))
5273
5099
b_other = Branch.open(location)
5275
5101
b.bind(b_other)
6226
6051
from bzrlib import switch
6227
6052
tree_location = directory
6228
6053
revision = _get_one_revision('switch', revision)
6229
possible_transports = []
6230
control_dir = controldir.ControlDir.open_containing(tree_location,
6231
possible_transports=possible_transports)[0]
6054
control_dir = controldir.ControlDir.open_containing(tree_location)[0]
6232
6055
if to_location is None:
6233
6056
if revision is None:
6234
6057
raise errors.BzrCommandError(gettext('You must supply either a'
6235
6058
' revision or a location'))
6236
6059
to_location = tree_location
6238
branch = control_dir.open_branch(
6239
possible_transports=possible_transports)
6061
branch = control_dir.open_branch()
6240
6062
had_explicit_nick = branch.get_config().has_explicit_nickname()
6241
6063
except errors.NotBranchError:
6243
6065
had_explicit_nick = False
6244
6066
if create_branch:
6245
6067
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)
6068
raise errors.BzrCommandError(gettext('cannot create branch without'
6070
to_location = directory_service.directories.dereference(
6072
if '/' not in to_location and '\\' not in to_location:
6073
# This path is meant to be relative to the existing branch
6074
this_url = self._get_branch_location(control_dir)
6075
# Perhaps the target control dir supports colocated branches?
6077
root = controldir.ControlDir.open(this_url,
6078
possible_transports=[control_dir.user_transport])
6079
except errors.NotBranchError:
6082
colocated = root._format.colocated_branches
6084
to_location = urlutils.join_segment_parameters(this_url,
6085
{"branch": urlutils.escape(to_location)})
6087
to_location = urlutils.join(
6088
this_url, '..', urlutils.escape(to_location))
6250
6089
to_branch = branch.bzrdir.sprout(to_location,
6251
possible_transports=possible_transports,
6252
source_branch=branch).open_branch()
6090
possible_transports=[branch.bzrdir.root_transport],
6091
source_branch=branch).open_branch()
6254
to_branch = lookup_sibling_branch(control_dir, to_location)
6093
# Perhaps it's a colocated branch?
6095
to_branch = control_dir.open_branch(to_location)
6096
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
6098
to_branch = Branch.open(to_location)
6099
except errors.NotBranchError:
6100
this_url = self._get_branch_location(control_dir)
6101
to_branch = Branch.open(
6103
this_url, '..', urlutils.escape(to_location)))
6255
6104
if revision is not None:
6256
6105
revision = revision.as_revision_id(to_branch)
6257
6106
switch.switch(control_dir, to_branch, force, revision_id=revision)
6261
6110
note(gettext('Switched to branch: %s'),
6262
6111
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6113
def _get_branch_location(self, control_dir):
6114
"""Return location of branch for this control dir."""
6116
this_branch = control_dir.open_branch()
6117
# This may be a heavy checkout, where we want the master branch
6118
master_location = this_branch.get_bound_location()
6119
if master_location is not None:
6120
return master_location
6121
# If not, use a local sibling
6122
return this_branch.base
6123
except errors.NotBranchError:
6124
format = control_dir.find_branch_format()
6125
if getattr(format, 'get_reference', None) is not None:
6126
return format.get_reference(control_dir)
6128
return control_dir.root_transport.base
6266
6131
class cmd_view(Command):
6674
6539
takes_options = [Option('plugin',
6675
6540
help='Export help text from named command '\
6676
6541
'(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):
6544
def run(self, plugin=None):
6684
6545
from bzrlib.export_pot import export_pot
6685
export_pot(self.outf, plugin, include_duplicates)
6546
export_pot(self.outf, plugin)
6688
6549
def _register_lazy_builtins():