86
86
def _get_branch_location(control_dir, possible_transports=None):
87
87
"""Return location of branch for this control dir."""
89
target = control_dir.get_branch_reference()
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
90
97
except errors.NotBranchError:
91
return control_dir.root_transport.base
92
if target is not None:
94
this_branch = control_dir.open_branch(
95
possible_transports=possible_transports)
96
# This may be a heavy checkout, where we want the master branch
97
master_location = this_branch.get_bound_location()
98
if master_location is not None:
99
return master_location
100
# If not, use a local sibling
101
return this_branch.base
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
104
105
def _is_colocated(control_dir, possible_transports=None):
105
106
"""Check if the branch in control_dir is colocated.
107
108
:param control_dir: Control directory
108
:return: Tuple with boolean indicating whether the branch is colocated
109
and the full URL to the actual branch
109
:return: Boolean indicating whether
111
111
# This path is meant to be relative to the existing branch
112
112
this_url = _get_branch_location(control_dir,
132
132
def lookup_new_sibling_branch(control_dir, location, possible_transports=None):
133
133
"""Lookup the location for a new sibling branch.
135
:param control_dir: Control directory to find sibling branches from
135
:param control_dir: Control directory relative to which to look up
136
137
:param location: Name of the new branch
137
138
:return: Full location to the new branch
151
def open_sibling_branch(control_dir, location, possible_transports=None):
152
"""Open a branch, possibly a sibling of another.
152
def lookup_sibling_branch(control_dir, location, possible_transports=None):
153
"""Lookup sibling branch.
154
155
:param control_dir: Control directory relative to which to lookup the
156
157
:param location: Location to look up
161
162
return control_dir.open_branch(location,
162
163
possible_transports=possible_transports)
163
164
except (errors.NotBranchError, errors.NoColocatedBranchSupport):
164
this_url = _get_branch_location(control_dir)
167
this_url, '..', urlutils.escape(location)))
170
def open_nearby_branch(near=None, location=None, possible_transports=None):
171
"""Open a nearby branch.
173
:param near: Optional location of container from which to open branch
174
:param location: Location of the branch
175
:return: Branch instance
181
return Branch.open(location,
182
possible_transports=possible_transports)
166
return Branch.open(location)
183
167
except errors.NotBranchError:
185
cdir = controldir.ControlDir.open(near,
186
possible_transports=possible_transports)
187
return open_sibling_branch(cdir, location,
188
possible_transports=possible_transports)
191
def iter_sibling_branches(control_dir, possible_transports=None):
192
"""Iterate over the siblings of a branch.
194
:param control_dir: Control directory for which to look up the siblings
195
:return: Iterator over tuples with branch name and branch object
199
reference = control_dir.get_branch_reference()
200
except errors.NotBranchError:
201
# There is no active branch, just return the colocated branches.
202
for name, branch in control_dir.get_branches().iteritems():
205
if reference is not None:
206
ref_branch = Branch.open(reference,
207
possible_transports=possible_transports)
210
if ref_branch is None or ref_branch.name:
211
if ref_branch is not None:
212
control_dir = ref_branch.bzrdir
213
for name, branch in control_dir.get_branches().iteritems():
216
repo = ref_branch.bzrdir.find_repository()
217
for branch in repo.find_branches(using=True):
218
name = urlutils.relative_url(repo.user_url,
219
branch.user_url).rstrip("/")
168
this_url = _get_branch_location(control_dir)
171
this_url, '..', urlutils.escape(location)))
174
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
175
def tree_files(file_list, default_branch=u'.', canonicalize=True,
177
return internal_tree_files(file_list, default_branch, canonicalize,
223
181
def tree_files_for_add(file_list):
246
# XXX: Bad function name; should possibly also be a class method of
247
# WorkingTree rather than a function.
248
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
249
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
251
"""Convert command-line paths to a WorkingTree and relative paths.
253
Deprecated: use WorkingTree.open_containing_paths instead.
255
This is typically used for command-line processors that take one or
256
more filenames, and infer the workingtree that contains them.
258
The filenames given are not required to exist.
260
:param file_list: Filenames to convert.
262
:param default_branch: Fallback tree path to use if file_list is empty or
265
:param apply_view: if True and a view is set, apply it or check that
266
specified files are within it
268
:return: workingtree, [relative_paths]
270
return WorkingTree.open_containing_paths(
271
file_list, default_directory='.',
288
276
def _get_view_info_for_change_reporter(tree):
289
277
"""Get the view information from a tree for change reporting."""
953
self.add_cleanup(tree.lock_read().unlock)
954
940
if file_list is not None:
955
941
file_ids = tree.paths2ids(file_list, trees=extra_trees,
956
942
require_versioned=True)
957
943
# find_ids_across_trees may include some paths that don't
958
944
# exist in 'tree'.
959
entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
946
(tree.id2path(file_id), tree.inventory[file_id])
947
for file_id in file_ids if tree.has_id(file_id))
961
entries = tree.iter_entries_by_dir()
949
entries = tree.inventory.entries()
963
for path, entry in sorted(entries):
952
for path, entry in entries:
964
953
if kind and kind != entry.kind:
969
956
self.outf.write('%-50s %s\n' % (path, entry.file_id))
1163
1149
def run(self, location=None, remember=None, overwrite=False,
1164
1150
revision=None, verbose=False,
1165
1151
directory=None, local=False,
1166
show_base=False, overwrite_tags=False):
1169
overwrite = ["history", "tags"]
1170
elif overwrite_tags:
1171
overwrite = ["tags"]
1174
1153
# FIXME: too much stuff is in the command class
1175
1154
revision_id = None
1176
1155
mergeable = None
1185
1164
branch_to = Branch.open_containing(directory)[0]
1186
1165
self.add_cleanup(branch_to.lock_write().unlock)
1188
warning(gettext("No working tree, ignoring --show-base"))
1167
if tree_to is None and show_base:
1168
raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
1190
1170
if local and not branch_to.get_bound_location():
1191
1171
raise errors.LocalRequiresBoundBranch()
1322
1298
def run(self, location=None, remember=None, overwrite=False,
1323
1299
create_prefix=False, verbose=False, revision=None,
1324
1300
use_existing_dir=False, directory=None, stacked_on=None,
1325
stacked=False, strict=None, no_tree=False,
1326
overwrite_tags=False):
1301
stacked=False, strict=None, no_tree=False):
1327
1302
from bzrlib.push import _show_push_branch
1330
overwrite = ["history", "tags"]
1331
elif overwrite_tags:
1332
overwrite = ["tags"]
1336
1304
if directory is None:
1337
1305
directory = '.'
1338
1306
# Get the source branch
1680
1649
def run(self, dir=u'.'):
1681
1650
tree = WorkingTree.open_containing(dir)[0]
1682
1651
self.add_cleanup(tree.lock_read().unlock)
1652
new_inv = tree.inventory
1683
1653
old_tree = tree.basis_tree()
1684
1654
self.add_cleanup(old_tree.lock_read().unlock)
1655
old_inv = old_tree.inventory
1686
1657
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1687
1658
for f, paths, c, v, p, n, k, e in iterator:
1870
1841
title='Deletion Strategy', value_switches=True, enum_switch=False,
1871
1842
safe='Backup changed files (default).',
1872
1843
keep='Delete from bzr but leave the working copy.',
1873
no_backup='Don\'t backup changed files.'),
1844
no_backup='Don\'t backup changed files.',
1845
force='Delete all the specified files, even if they can not be '
1846
'recovered and even if they are non-empty directories. '
1847
'(deprecated, use no-backup)')]
1875
1848
aliases = ['rm', 'del']
1876
1849
encoding_type = 'replace'
1878
1851
def run(self, file_list, verbose=False, new=False,
1879
1852
file_deletion_strategy='safe'):
1853
if file_deletion_strategy == 'force':
1854
note(gettext("(The --force option is deprecated, rather use --no-backup "
1856
file_deletion_strategy = 'no-backup'
1881
1858
tree, file_list = WorkingTree.open_containing_paths(file_list)
2328
2305
help='Diff format to use.',
2329
2306
lazy_registry=('bzrlib.diff', 'format_registry'),
2330
2307
title='Diff format'),
2332
help='How many lines of context to show.',
2336
2309
aliases = ['di', 'dif']
2337
2310
encoding_type = 'exact'
2339
2312
@display_command
2340
2313
def run(self, revision=None, file_list=None, diff_options=None,
2341
prefix=None, old=None, new=None, using=None, format=None,
2314
prefix=None, old=None, new=None, using=None, format=None):
2343
2315
from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
2344
2316
show_diff_trees)
2444
2416
self.add_cleanup(wt.lock_read().unlock)
2445
2417
basis = wt.basis_tree()
2446
2418
self.add_cleanup(basis.lock_read().unlock)
2447
root_id = wt.get_root_id()
2448
for file_id in wt.all_file_ids():
2449
if basis.has_id(file_id):
2451
if root_id == file_id:
2453
path = wt.id2path(file_id)
2419
basis_inv = basis.inventory
2422
if basis_inv.has_id(file_id):
2424
if inv.is_root(file_id) and len(basis_inv) == 0:
2426
path = inv.id2path(file_id)
2454
2427
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
3544
3517
tokens = fixed_bug.split(':')
3545
3518
if len(tokens) == 1:
3546
3519
if default_bugtracker is None:
3547
branch_config = branch.get_config_stack()
3548
default_bugtracker = branch_config.get(
3520
branch_config = branch.get_config()
3521
default_bugtracker = branch_config.get_user_option(
3550
3523
if default_bugtracker is None:
3551
3524
raise errors.BzrCommandError(gettext(
3901
3872
class cmd_nick(Command):
3902
3873
__doc__ = """Print or set the branch nickname.
3904
If unset, the colocated branch name is used for colocated branches, and
3905
the branch directory name is used for other branches. To print the
3906
current nickname, execute with no argument.
3875
If unset, the tree root directory name is used as the nickname.
3876
To print the current nickname, execute with no argument.
3908
3878
Bound branches use the nickname of its master branch unless it is set
4705
4675
if tree.kind(file_id) != "directory":
4708
# FIXME: Support nested trees
4709
for name, ie in tree.root_inventory.iter_entries(file_id):
4678
for name, ie in tree.inventory.iter_entries(file_id):
4710
4679
interesting_ids.add(ie.file_id)
4711
4680
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4747
4716
class cmd_revert(Command):
4749
Set files in the working tree back to the contents of a previous revision.
4717
__doc__ = """Revert files to a previous revision.
4751
4719
Giving a list of files will revert only those files. Otherwise, all files
4752
4720
will be reverted. If the revision is not specified with '--revision', the
4753
working tree basis revision is used. A revert operation affects only the
4754
working tree, not any revision history like the branch and repository or
4755
the working tree basis revision.
4721
last committed revision is used.
4757
4723
To remove only some changes, without reverting to a prior version, use
4758
4724
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4759
4725
will remove the changes introduced by the second last commit (-2), without
4760
4726
affecting the changes introduced by the last commit (-1). To remove
4761
4727
certain changes on a hunk-by-hunk basis, see the shelve command.
4762
To update the branch to a specific revision or the latest revision and
4763
update the working tree accordingly while preserving local changes, see the
4766
Uncommitted changes to files that are reverted will be discarded.
4767
Howver, by default, any files that have been manually changed will be
4768
backed up first. (Files changed only by merge are not backed up.) Backup
4769
files have '.~#~' appended to their name, where # is a number.
4729
By default, any files that have been manually changed will be backed up
4730
first. (Files changed only by merge are not backed up.) Backup files have
4731
'.~#~' appended to their name, where # is a number.
4771
4733
When you provide files, you can use their current pathname or the pathname
4772
4734
from the target revision. So you can use revert to "undelete" a file by
5159
5113
rev_id = revision[0].as_revision_id(b)
5160
5114
t = testament_class.from_revision(b.repository, rev_id)
5162
self.outf.writelines(t.as_text_lines())
5116
sys.stdout.writelines(t.as_text_lines())
5164
self.outf.write(t.as_short_text())
5118
sys.stdout.write(t.as_short_text())
5167
5121
class cmd_annotate(Command):
5309
5263
if location is None:
5310
5264
if b.get_bound_location() is not None:
5311
raise errors.BzrCommandError(
5312
gettext('Branch is already bound'))
5265
raise errors.BzrCommandError(gettext('Branch is already bound'))
5314
raise errors.BzrCommandError(
5315
gettext('No location supplied'
5316
' and no previous location known'))
5267
raise errors.BzrCommandError(gettext('No location supplied '
5268
'and no previous location known'))
5317
5269
b_other = Branch.open(location)
5319
5271
b.bind(b_other)
5523
5475
help="Protocol to serve.",
5524
5476
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5525
5477
value_switches=True),
5527
help='Listen for connections on nominated address.', type=str),
5529
help='Listen for connections on nominated port. Passing 0 as '
5530
'the port number will result in a dynamically allocated '
5531
'port. The default port depends on the protocol.',
5479
help='Listen for connections on nominated port of the form '
5480
'[hostname:]portnumber. Passing 0 as the port number will '
5481
'result in a dynamically allocated port. The default port '
5482
'depends on the protocol.',
5533
5484
custom_help('directory',
5534
5485
help='Serve contents of this directory.'),
5535
5486
Option('allow-writes',
5545
5496
help='Override the default idle client timeout (5min).'),
5548
def run(self, listen=None, port=None, inet=False, directory=None,
5549
allow_writes=False, protocol=None, client_timeout=None):
5499
def get_host_and_port(self, port):
5500
"""Return the host and port to run the smart server on.
5502
If 'port' is None, None will be returned for the host and port.
5504
If 'port' has a colon in it, the string before the colon will be
5505
interpreted as the host.
5507
:param port: A string of the port to run the server on.
5508
:return: A tuple of (host, port), where 'host' is a host name or IP,
5509
and port is an integer TCP/IP port.
5512
if port is not None:
5514
host, port = port.split(':')
5518
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5519
protocol=None, client_timeout=None):
5550
5520
from bzrlib import transport
5551
5521
if directory is None:
5552
5522
directory = os.getcwd()
5553
5523
if protocol is None:
5554
5524
protocol = transport.transport_server_registry.get()
5525
host, port = self.get_host_and_port(port)
5555
5526
url = transport.location_to_url(directory)
5556
5527
if not allow_writes:
5557
5528
url = 'readonly+' + url
5558
5529
t = transport.get_transport_from_url(url)
5559
protocol(t, listen, port, inet, client_timeout)
5531
protocol(t, host, port, inet, client_timeout)
5532
except TypeError, e:
5533
# We use symbol_versioning.deprecated_in just so that people
5534
# grepping can find it here.
5535
# symbol_versioning.deprecated_in((2, 5, 0))
5536
symbol_versioning.warn(
5537
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5538
'Most likely it needs to be updated to support a'
5539
' "timeout" parameter (added in bzr 2.5.0)'
5540
% (e, protocol.__module__, protocol),
5542
protocol(t, host, port, inet)
5562
5545
class cmd_join(Command):
6232
6214
Option('create-branch', short_name='b',
6233
6215
help='Create the target branch from this one before'
6234
6216
' switching to it.'),
6236
help='Store and restore uncommitted changes in the'
6240
6219
def run(self, to_location=None, force=False, create_branch=False,
6241
revision=None, directory=u'.', store=False):
6220
revision=None, directory=u'.'):
6242
6221
from bzrlib import switch
6243
6222
tree_location = directory
6244
6223
revision = _get_one_revision('switch', revision)
6267
6246
possible_transports=possible_transports,
6268
6247
source_branch=branch).open_branch()
6271
to_branch = Branch.open(to_location,
6272
possible_transports=possible_transports)
6273
except errors.NotBranchError:
6274
to_branch = open_sibling_branch(control_dir, to_location,
6275
possible_transports=possible_transports)
6249
to_branch = lookup_sibling_branch(control_dir, to_location)
6276
6250
if revision is not None:
6277
6251
revision = revision.as_revision_id(to_branch)
6278
switch.switch(control_dir, to_branch, force, revision_id=revision,
6279
store_uncommitted=store)
6252
switch.switch(control_dir, to_branch, force, revision_id=revision)
6280
6253
if had_explicit_nick:
6281
6254
branch = control_dir.open_branch() #get the new branch!
6282
6255
branch.nick = to_branch.nick
6477
6450
takes_args = ["location?"]
6479
takes_options = ['directory',
6480
Option('force', help='Remove branch even if it is the active branch.')]
6482
6452
aliases = ["rmbranch"]
6484
def run(self, directory=None, location=None, force=False):
6485
br = open_nearby_branch(near=directory, location=location)
6486
if not force and br.bzrdir.has_workingtree():
6488
active_branch = br.bzrdir.open_branch(name="")
6489
except errors.NotBranchError:
6490
active_branch = None
6491
if (active_branch is not None and
6492
br.control_url == active_branch.control_url):
6493
raise errors.BzrCommandError(
6494
gettext("Branch is active. Use --force to remove it."))
6495
br.bzrdir.destroy_branch(br.name)
6454
def run(self, location=None):
6455
if location is None:
6457
branch = Branch.open_containing(location)[0]
6458
branch.bzrdir.destroy_branch()
6498
6461
class cmd_shelve(Command):
6727
6690
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6728
6691
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6729
6692
('cmd_conflicts', [], 'bzrlib.conflicts'),
6730
('cmd_ping', [], 'bzrlib.smart.ping'),
6731
6693
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6732
('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
6694
('cmd_verify_signatures', [],
6695
'bzrlib.commit_signature_commands'),
6733
6696
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6735
6698
builtin_command_registry.register_lazy(name, aliases, module_name)