86
86
def _get_branch_location(control_dir, possible_transports=None):
87
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
89
target = control_dir.get_branch_reference()
97
90
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
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
105
104
def _is_colocated(control_dir, possible_transports=None):
106
105
"""Check if the branch in control_dir is colocated.
108
107
:param control_dir: Control directory
109
:return: Boolean indicating whether
108
:return: Tuple with boolean indicating whether the branch is colocated
109
and the full URL to the actual branch
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 relative to which to look up
135
:param control_dir: Control directory to find sibling branches from
137
136
:param location: Name of the new branch
138
137
:return: Full location to the new branch
152
def lookup_sibling_branch(control_dir, location, possible_transports=None):
153
"""Lookup sibling branch.
151
def open_sibling_branch(control_dir, location, possible_transports=None):
152
"""Open a branch, possibly a sibling of another.
155
154
:param control_dir: Control directory relative to which to lookup the
157
156
:param location: Location to look up
162
161
return control_dir.open_branch(location,
163
162
possible_transports=possible_transports)
164
163
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
166
return Branch.open(location)
181
return Branch.open(location,
182
possible_transports=possible_transports)
167
183
except errors.NotBranchError:
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,
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("/")
181
223
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='.',
276
288
def _get_view_info_for_change_reporter(tree):
277
289
"""Get the view information from a tree for change reporting."""
953
self.add_cleanup(tree.lock_read().unlock)
940
954
if file_list is not None:
941
955
file_ids = tree.paths2ids(file_list, trees=extra_trees,
942
956
require_versioned=True)
943
957
# find_ids_across_trees may include some paths that don't
944
958
# exist in 'tree'.
946
(tree.id2path(file_id), tree.inventory[file_id])
947
for file_id in file_ids if tree.has_id(file_id))
959
entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
949
entries = tree.inventory.entries()
961
entries = tree.iter_entries_by_dir()
952
for path, entry in entries:
963
for path, entry in sorted(entries):
953
964
if kind and kind != entry.kind:
956
969
self.outf.write('%-50s %s\n' % (path, entry.file_id))
1149
1163
def run(self, location=None, remember=None, overwrite=False,
1150
1164
revision=None, verbose=False,
1151
1165
directory=None, local=False,
1166
show_base=False, overwrite_tags=False):
1169
overwrite = ["history", "tags"]
1170
elif overwrite_tags:
1171
overwrite = ["tags"]
1153
1174
# FIXME: too much stuff is in the command class
1154
1175
revision_id = None
1155
1176
mergeable = None
1164
1185
branch_to = Branch.open_containing(directory)[0]
1165
1186
self.add_cleanup(branch_to.lock_write().unlock)
1167
if tree_to is None and show_base:
1168
raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
1188
warning(gettext("No working tree, ignoring --show-base"))
1170
1190
if local and not branch_to.get_bound_location():
1171
1191
raise errors.LocalRequiresBoundBranch()
1298
1322
def run(self, location=None, remember=None, overwrite=False,
1299
1323
create_prefix=False, verbose=False, revision=None,
1300
1324
use_existing_dir=False, directory=None, stacked_on=None,
1301
stacked=False, strict=None, no_tree=False):
1325
stacked=False, strict=None, no_tree=False,
1326
overwrite_tags=False):
1302
1327
from bzrlib.push import _show_push_branch
1330
overwrite = ["history", "tags"]
1331
elif overwrite_tags:
1332
overwrite = ["tags"]
1304
1336
if directory is None:
1305
1337
directory = '.'
1306
1338
# Get the source branch
1649
1680
def run(self, dir=u'.'):
1650
1681
tree = WorkingTree.open_containing(dir)[0]
1651
1682
self.add_cleanup(tree.lock_read().unlock)
1652
new_inv = tree.inventory
1653
1683
old_tree = tree.basis_tree()
1654
1684
self.add_cleanup(old_tree.lock_read().unlock)
1655
old_inv = old_tree.inventory
1657
1686
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1658
1687
for f, paths, c, v, p, n, k, e in iterator:
1841
1870
title='Deletion Strategy', value_switches=True, enum_switch=False,
1842
1871
safe='Backup changed files (default).',
1843
1872
keep='Delete from bzr but leave the working copy.',
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)')]
1873
no_backup='Don\'t backup changed files.'),
1848
1875
aliases = ['rm', 'del']
1849
1876
encoding_type = 'replace'
1851
1878
def run(self, file_list, verbose=False, new=False,
1852
1879
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'
1858
1881
tree, file_list = WorkingTree.open_containing_paths(file_list)
2305
2328
help='Diff format to use.',
2306
2329
lazy_registry=('bzrlib.diff', 'format_registry'),
2307
2330
title='Diff format'),
2332
help='How many lines of context to show.',
2309
2336
aliases = ['di', 'dif']
2310
2337
encoding_type = 'exact'
2312
2339
@display_command
2313
2340
def run(self, revision=None, file_list=None, diff_options=None,
2314
prefix=None, old=None, new=None, using=None, format=None):
2341
prefix=None, old=None, new=None, using=None, format=None,
2315
2343
from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
2316
2344
show_diff_trees)
2416
2444
self.add_cleanup(wt.lock_read().unlock)
2417
2445
basis = wt.basis_tree()
2418
2446
self.add_cleanup(basis.lock_read().unlock)
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)
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)
2427
2454
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
3517
3544
tokens = fixed_bug.split(':')
3518
3545
if len(tokens) == 1:
3519
3546
if default_bugtracker is None:
3520
branch_config = branch.get_config()
3521
default_bugtracker = branch_config.get_user_option(
3547
branch_config = branch.get_config_stack()
3548
default_bugtracker = branch_config.get(
3523
3550
if default_bugtracker is None:
3524
3551
raise errors.BzrCommandError(gettext(
4676
4705
if tree.kind(file_id) != "directory":
4679
for name, ie in tree.inventory.iter_entries(file_id):
4708
# FIXME: Support nested trees
4709
for name, ie in tree.root_inventory.iter_entries(file_id):
4680
4710
interesting_ids.add(ie.file_id)
4681
4711
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4717
4747
class cmd_revert(Command):
4718
__doc__ = """Revert files to a previous revision.
4749
Set files in the working tree back to the contents of a previous revision.
4720
4751
Giving a list of files will revert only those files. Otherwise, all files
4721
4752
will be reverted. If the revision is not specified with '--revision', the
4722
last committed revision is used.
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.
4724
4757
To remove only some changes, without reverting to a prior version, use
4725
4758
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4726
4759
will remove the changes introduced by the second last commit (-2), without
4727
4760
affecting the changes introduced by the last commit (-1). To remove
4728
4761
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
4730
By default, any files that have been manually changed will be backed up
4731
first. (Files changed only by merge are not backed up.) Backup files have
4732
'.~#~' appended to their name, where # is a number.
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.
4734
4771
When you provide files, you can use their current pathname or the pathname
4735
4772
from the target revision. So you can use revert to "undelete" a file by
5114
5159
rev_id = revision[0].as_revision_id(b)
5115
5160
t = testament_class.from_revision(b.repository, rev_id)
5117
sys.stdout.writelines(t.as_text_lines())
5162
self.outf.writelines(t.as_text_lines())
5119
sys.stdout.write(t.as_short_text())
5164
self.outf.write(t.as_short_text())
5122
5167
class cmd_annotate(Command):
5264
5309
if location is None:
5265
5310
if b.get_bound_location() is not None:
5266
raise errors.BzrCommandError(gettext('Branch is already bound'))
5311
raise errors.BzrCommandError(
5312
gettext('Branch is already bound'))
5268
raise errors.BzrCommandError(gettext('No location supplied '
5269
'and no previous location known'))
5314
raise errors.BzrCommandError(
5315
gettext('No location supplied'
5316
' and no previous location known'))
5270
5317
b_other = Branch.open(location)
5272
5319
b.bind(b_other)
5476
5523
help="Protocol to serve.",
5477
5524
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5478
5525
value_switches=True),
5527
help='Listen for connections on nominated address.', type=str),
5480
help='Listen for connections on nominated port of the form '
5481
'[hostname:]portnumber. Passing 0 as the port number will '
5482
'result in a dynamically allocated port. The default port '
5483
'depends on the protocol.',
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.',
5485
5533
custom_help('directory',
5486
5534
help='Serve contents of this directory.'),
5487
5535
Option('allow-writes',
5497
5545
help='Override the default idle client timeout (5min).'),
5500
def get_host_and_port(self, port):
5501
"""Return the host and port to run the smart server on.
5503
If 'port' is None, None will be returned for the host and port.
5505
If 'port' has a colon in it, the string before the colon will be
5506
interpreted as the host.
5508
:param port: A string of the port to run the server on.
5509
:return: A tuple of (host, port), where 'host' is a host name or IP,
5510
and port is an integer TCP/IP port.
5513
if port is not None:
5515
host, port = port.split(':')
5519
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5520
protocol=None, client_timeout=None):
5548
def run(self, listen=None, port=None, inet=False, directory=None,
5549
allow_writes=False, protocol=None, client_timeout=None):
5521
5550
from bzrlib import transport
5522
5551
if directory is None:
5523
5552
directory = os.getcwd()
5524
5553
if protocol is None:
5525
5554
protocol = transport.transport_server_registry.get()
5526
host, port = self.get_host_and_port(port)
5527
5555
url = transport.location_to_url(directory)
5528
5556
if not allow_writes:
5529
5557
url = 'readonly+' + url
5530
5558
t = transport.get_transport_from_url(url)
5532
protocol(t, host, port, inet, client_timeout)
5533
except TypeError, e:
5534
# We use symbol_versioning.deprecated_in just so that people
5535
# grepping can find it here.
5536
# symbol_versioning.deprecated_in((2, 5, 0))
5537
symbol_versioning.warn(
5538
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5539
'Most likely it needs to be updated to support a'
5540
' "timeout" parameter (added in bzr 2.5.0)'
5541
% (e, protocol.__module__, protocol),
5543
protocol(t, host, port, inet)
5559
protocol(t, listen, port, inet, client_timeout)
5546
5562
class cmd_join(Command):
6215
6232
Option('create-branch', short_name='b',
6216
6233
help='Create the target branch from this one before'
6217
6234
' switching to it.'),
6236
help='Store and restore uncommitted changes in the'
6220
6240
def run(self, to_location=None, force=False, create_branch=False,
6221
revision=None, directory=u'.'):
6241
revision=None, directory=u'.', store=False):
6222
6242
from bzrlib import switch
6223
6243
tree_location = directory
6224
6244
revision = _get_one_revision('switch', revision)
6247
6267
possible_transports=possible_transports,
6248
6268
source_branch=branch).open_branch()
6250
to_branch = lookup_sibling_branch(control_dir, to_location)
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)
6251
6276
if revision is not None:
6252
6277
revision = revision.as_revision_id(to_branch)
6253
switch.switch(control_dir, to_branch, force, revision_id=revision)
6278
switch.switch(control_dir, to_branch, force, revision_id=revision,
6279
store_uncommitted=store)
6254
6280
if had_explicit_nick:
6255
6281
branch = control_dir.open_branch() #get the new branch!
6256
6282
branch.nick = to_branch.nick
6451
6477
takes_args = ["location?"]
6479
takes_options = ['directory',
6480
Option('force', help='Remove branch even if it is the active branch.')]
6453
6482
aliases = ["rmbranch"]
6455
def run(self, location=None):
6456
if location is None:
6458
cdir = controldir.ControlDir.open_containing(location)[0]
6459
cdir.destroy_branch()
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)
6462
6498
class cmd_shelve(Command):
6691
6727
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6692
6728
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6693
6729
('cmd_conflicts', [], 'bzrlib.conflicts'),
6730
('cmd_ping', [], 'bzrlib.smart.ping'),
6694
6731
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6695
('cmd_verify_signatures', [],
6696
'bzrlib.commit_signature_commands'),
6732
('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
6697
6733
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6699
6735
builtin_command_registry.register_lazy(name, aliases, module_name)