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
151
def open_sibling_branch(control_dir, location, possible_transports=None):
153
"""Open a branch, possibly a sibling.
152
"""Open a branch, possibly a sibling of another.
155
154
:param control_dir: Control directory relative to which to lookup the
189
188
possible_transports=possible_transports)
192
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
193
def tree_files(file_list, default_branch=u'.', canonicalize=True,
195
return internal_tree_files(file_list, default_branch, canonicalize,
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("/")
199
223
def tree_files_for_add(file_list):
264
# XXX: Bad function name; should possibly also be a class method of
265
# WorkingTree rather than a function.
266
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
267
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
269
"""Convert command-line paths to a WorkingTree and relative paths.
271
Deprecated: use WorkingTree.open_containing_paths instead.
273
This is typically used for command-line processors that take one or
274
more filenames, and infer the workingtree that contains them.
276
The filenames given are not required to exist.
278
:param file_list: Filenames to convert.
280
:param default_branch: Fallback tree path to use if file_list is empty or
283
:param apply_view: if True and a view is set, apply it or check that
284
specified files are within it
286
:return: workingtree, [relative_paths]
288
return WorkingTree.open_containing_paths(
289
file_list, default_directory='.',
294
288
def _get_view_info_for_change_reporter(tree):
295
289
"""Get the view information from a tree for change reporting."""
374
368
This will produce the same results as calling 'bzr diff --summarize'.
377
# TODO: --no-recurse, --recurse options
371
# TODO: --no-recurse/-N, --recurse options
379
373
takes_args = ['file*']
380
374
takes_options = ['show-ids', 'revision', 'change', 'verbose',
692
686
if len(revision) != 1:
693
687
raise errors.BzrCommandError(gettext(
694
"Tags can only be placed on a single revision, "
688
"Revision numbers only make sense for single "
689
"revisions, not ranges"))
696
690
revid = revision[0].as_revision_id(b)
698
692
revid = b.last_revision()
953
self.add_cleanup(tree.lock_read().unlock)
958
954
if file_list is not None:
959
955
file_ids = tree.paths2ids(file_list, trees=extra_trees,
960
956
require_versioned=True)
961
957
# find_ids_across_trees may include some paths that don't
962
958
# exist in 'tree'.
964
(tree.id2path(file_id), tree.inventory[file_id])
965
for file_id in file_ids if tree.has_id(file_id))
959
entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
967
entries = tree.inventory.entries()
961
entries = tree.iter_entries_by_dir()
970
for path, entry in entries:
963
for path, entry in sorted(entries):
971
964
if kind and kind != entry.kind:
974
969
self.outf.write('%-50s %s\n' % (path, entry.file_id))
1047
1042
and rel_names[0].lower() == rel_names[1].lower()):
1048
1043
into_existing = False
1050
inv = tree.inventory
1051
1045
# 'fix' the case of a potential 'from'
1052
1046
from_id = tree.path2id(
1053
1047
tree.get_canonical_inventory_path(rel_names[0]))
1054
1048
if (not osutils.lexists(names_list[0]) and
1055
from_id and inv.get_file_kind(from_id) == "directory"):
1049
from_id and tree.stored_kind(from_id) == "directory"):
1056
1050
into_existing = False
1058
1052
if into_existing:
1159
1153
"the master branch."
1161
1155
Option('show-base',
1162
help="Show base revision text in conflicts.")
1156
help="Show base revision text in conflicts."),
1157
Option('overwrite-tags',
1158
help="Overwrite tags only."),
1164
1160
takes_args = ['location?']
1165
1161
encoding_type = 'replace'
1167
1163
def run(self, location=None, remember=None, overwrite=False,
1168
1164
revision=None, verbose=False,
1169
1165
directory=None, local=False,
1166
show_base=False, overwrite_tags=False):
1169
overwrite = ["history", "tags"]
1170
elif overwrite_tags:
1171
overwrite = ["tags"]
1171
1174
# FIXME: too much stuff is in the command class
1172
1175
revision_id = None
1173
1176
mergeable = None
1182
1185
branch_to = Branch.open_containing(directory)[0]
1183
1186
self.add_cleanup(branch_to.lock_write().unlock)
1185
if tree_to is None and show_base:
1186
raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
1188
warning(gettext("No working tree, ignoring --show-base"))
1188
1190
if local and not branch_to.get_bound_location():
1189
1191
raise errors.LocalRequiresBoundBranch()
1316
1322
def run(self, location=None, remember=None, overwrite=False,
1317
1323
create_prefix=False, verbose=False, revision=None,
1318
1324
use_existing_dir=False, directory=None, stacked_on=None,
1319
stacked=False, strict=None, no_tree=False):
1325
stacked=False, strict=None, no_tree=False,
1326
overwrite_tags=False):
1320
1327
from bzrlib.push import _show_push_branch
1330
overwrite = ["history", "tags"]
1331
elif overwrite_tags:
1332
overwrite = ["tags"]
1322
1336
if directory is None:
1323
1337
directory = '.'
1324
1338
# Get the source branch
1558
1572
active_branch = dir.open_branch(name="")
1559
1573
except errors.NotBranchError:
1560
1574
active_branch = None
1561
branches = dir.get_branches()
1563
for name, branch in branches.iteritems():
1576
for name, branch in iter_sibling_branches(dir):
1566
1579
active = (active_branch is not None and
1604
_see_also = ['checkouts', 'branch']
1617
_see_also = ['checkouts', 'branch', 'working-trees', 'remove-tree']
1605
1618
takes_args = ['branch_location?', 'to_location?']
1606
1619
takes_options = ['revision',
1607
1620
Option('lightweight',
1667
1680
def run(self, dir=u'.'):
1668
1681
tree = WorkingTree.open_containing(dir)[0]
1669
1682
self.add_cleanup(tree.lock_read().unlock)
1670
new_inv = tree.inventory
1671
1683
old_tree = tree.basis_tree()
1672
1684
self.add_cleanup(old_tree.lock_read().unlock)
1673
old_inv = old_tree.inventory
1675
1686
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1676
1687
for f, paths, c, v, p, n, k, e in iterator:
1848
1859
This makes Bazaar stop tracking changes to the specified files. Bazaar will
1849
1860
delete them if they can easily be recovered using revert otherwise they
1850
will be backed up (adding an extention of the form .~#~). If no options or
1861
will be backed up (adding an extension of the form .~#~). If no options or
1851
1862
parameters are given Bazaar will scan for files that are being tracked by
1852
1863
Bazaar but missing in your tree and stop tracking them for you.
1859
1870
title='Deletion Strategy', value_switches=True, enum_switch=False,
1860
1871
safe='Backup changed files (default).',
1861
1872
keep='Delete from bzr but leave the working copy.',
1862
no_backup='Don\'t backup changed files.',
1863
force='Delete all the specified files, even if they can not be '
1864
'recovered and even if they are non-empty directories. '
1865
'(deprecated, use no-backup)')]
1873
no_backup='Don\'t backup changed files.'),
1866
1875
aliases = ['rm', 'del']
1867
1876
encoding_type = 'replace'
1869
1878
def run(self, file_list, verbose=False, new=False,
1870
1879
file_deletion_strategy='safe'):
1871
if file_deletion_strategy == 'force':
1872
note(gettext("(The --force option is deprecated, rather use --no-backup "
1874
file_deletion_strategy = 'no-backup'
1876
1881
tree, file_list = WorkingTree.open_containing_paths(file_list)
2061
2066
RegistryOption('format',
2062
2067
help='Specify a format for this branch. '
2063
2068
'See "help formats".',
2064
lazy_registry=('bzrlib.bzrdir', 'format_registry'),
2069
lazy_registry=('bzrlib.controldir', 'format_registry'),
2065
2070
converter=lambda name: controldir.format_registry.make_bzrdir(name),
2066
2071
value_switches=True,
2067
2072
title="Branch format",
2323
2328
help='Diff format to use.',
2324
2329
lazy_registry=('bzrlib.diff', 'format_registry'),
2325
2330
title='Diff format'),
2332
help='How many lines of context to show.',
2327
2336
aliases = ['di', 'dif']
2328
2337
encoding_type = 'exact'
2330
2339
@display_command
2331
2340
def run(self, revision=None, file_list=None, diff_options=None,
2332
prefix=None, old=None, new=None, using=None, format=None):
2341
prefix=None, old=None, new=None, using=None, format=None,
2333
2343
from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
2334
2344
show_diff_trees)
2390
2400
self.add_cleanup(tree.lock_read().unlock)
2391
2401
old = tree.basis_tree()
2392
2402
self.add_cleanup(old.lock_read().unlock)
2393
for path, ie in old.inventory.iter_entries():
2403
for path, ie in old.iter_entries_by_dir():
2394
2404
if not tree.has_id(ie.file_id):
2395
2405
self.outf.write(path)
2434
2444
self.add_cleanup(wt.lock_read().unlock)
2435
2445
basis = wt.basis_tree()
2436
2446
self.add_cleanup(basis.lock_read().unlock)
2437
basis_inv = basis.inventory
2440
if basis_inv.has_id(file_id):
2442
if inv.is_root(file_id) and len(basis_inv) == 0:
2444
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)
2445
2454
if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
3535
3544
tokens = fixed_bug.split(':')
3536
3545
if len(tokens) == 1:
3537
3546
if default_bugtracker is None:
3538
branch_config = branch.get_config()
3539
default_bugtracker = branch_config.get_user_option(
3547
branch_config = branch.get_config_stack()
3548
default_bugtracker = branch_config.get(
3541
3550
if default_bugtracker is None:
3542
3551
raise errors.BzrCommandError(gettext(
4694
4705
if tree.kind(file_id) != "directory":
4697
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):
4698
4710
interesting_ids.add(ie.file_id)
4699
4711
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4735
4747
class cmd_revert(Command):
4736
__doc__ = """Revert files to a previous revision.
4749
Set files in the working tree back to the contents of a previous revision.
4738
4751
Giving a list of files will revert only those files. Otherwise, all files
4739
4752
will be reverted. If the revision is not specified with '--revision', the
4740
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.
4742
4757
To remove only some changes, without reverting to a prior version, use
4743
4758
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4744
4759
will remove the changes introduced by the second last commit (-2), without
4745
4760
affecting the changes introduced by the last commit (-1). To remove
4746
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
4748
By default, any files that have been manually changed will be backed up
4749
first. (Files changed only by merge are not backed up.) Backup files have
4750
'.~#~' 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.
4752
4771
When you provide files, you can use their current pathname or the pathname
4753
4772
from the target revision. So you can use revert to "undelete" a file by
5000
5019
"You have %d extra revisions:\n",
5001
5020
len(local_extra)) %
5002
5021
len(local_extra))
5023
if local_branch.supports_tags():
5024
rev_tag_dict = local_branch.tags.get_reverse_tag_dict()
5003
5025
for revision in iter_log_revisions(local_extra,
5004
5026
local_branch.repository,
5006
5029
lf.log_revision(revision)
5007
5030
printed_local = True
5008
5031
status_code = 1
5016
5039
"You are missing %d revisions:\n",
5017
5040
len(remote_extra)) %
5018
5041
len(remote_extra))
5042
if remote_branch.supports_tags():
5043
rev_tag_dict = remote_branch.tags.get_reverse_tag_dict()
5019
5044
for revision in iter_log_revisions(remote_extra,
5020
5045
remote_branch.repository,
5022
5048
lf.log_revision(revision)
5023
5049
status_code = 1
5132
5159
rev_id = revision[0].as_revision_id(b)
5133
5160
t = testament_class.from_revision(b.repository, rev_id)
5135
sys.stdout.writelines(t.as_text_lines())
5162
self.outf.writelines(t.as_text_lines())
5137
sys.stdout.write(t.as_short_text())
5164
self.outf.write(t.as_short_text())
5140
5167
class cmd_annotate(Command):
5282
5309
if location is None:
5283
5310
if b.get_bound_location() is not None:
5284
raise errors.BzrCommandError(gettext('Branch is already bound'))
5311
raise errors.BzrCommandError(
5312
gettext('Branch is already bound'))
5286
raise errors.BzrCommandError(gettext('No location supplied '
5287
'and no previous location known'))
5314
raise errors.BzrCommandError(
5315
gettext('No location supplied'
5316
' and no previous location known'))
5288
5317
b_other = Branch.open(location)
5290
5319
b.bind(b_other)
5494
5523
help="Protocol to serve.",
5495
5524
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5496
5525
value_switches=True),
5527
help='Listen for connections on nominated address.', type=str),
5498
help='Listen for connections on nominated port of the form '
5499
'[hostname:]portnumber. Passing 0 as the port number will '
5500
'result in a dynamically allocated port. The default port '
5501
'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.',
5503
5533
custom_help('directory',
5504
5534
help='Serve contents of this directory.'),
5505
5535
Option('allow-writes',
5515
5545
help='Override the default idle client timeout (5min).'),
5518
def get_host_and_port(self, port):
5519
"""Return the host and port to run the smart server on.
5521
If 'port' is None, None will be returned for the host and port.
5523
If 'port' has a colon in it, the string before the colon will be
5524
interpreted as the host.
5526
:param port: A string of the port to run the server on.
5527
:return: A tuple of (host, port), where 'host' is a host name or IP,
5528
and port is an integer TCP/IP port.
5531
if port is not None:
5533
host, port = port.split(':')
5537
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5538
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):
5539
5550
from bzrlib import transport
5540
5551
if directory is None:
5541
5552
directory = os.getcwd()
5542
5553
if protocol is None:
5543
5554
protocol = transport.transport_server_registry.get()
5544
host, port = self.get_host_and_port(port)
5545
5555
url = transport.location_to_url(directory)
5546
5556
if not allow_writes:
5547
5557
url = 'readonly+' + url
5548
5558
t = transport.get_transport_from_url(url)
5550
protocol(t, host, port, inet, client_timeout)
5551
except TypeError, e:
5552
# We use symbol_versioning.deprecated_in just so that people
5553
# grepping can find it here.
5554
# symbol_versioning.deprecated_in((2, 5, 0))
5555
symbol_versioning.warn(
5556
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5557
'Most likely it needs to be updated to support a'
5558
' "timeout" parameter (added in bzr 2.5.0)'
5559
% (e, protocol.__module__, protocol),
5561
protocol(t, host, port, inet)
5559
protocol(t, listen, port, inet, client_timeout)
5564
5562
class cmd_join(Command):
5700
5698
if public_branch is None:
5701
5699
public_branch = stored_public_branch
5702
5700
elif stored_public_branch is None:
5701
# FIXME: Should be done only if we succeed ? -- vila 2012-01-03
5703
5702
branch.set_public_branch(public_branch)
5704
5703
if not include_bundle and public_branch is None:
5705
5704
raise errors.BzrCommandError(gettext('No public branch specified or'
6233
6232
Option('create-branch', short_name='b',
6234
6233
help='Create the target branch from this one before'
6235
6234
' switching to it.'),
6236
help='Store and restore uncommitted changes in the'
6238
6240
def run(self, to_location=None, force=False, create_branch=False,
6239
revision=None, directory=u'.'):
6241
revision=None, directory=u'.', store=False):
6240
6242
from bzrlib import switch
6241
6243
tree_location = directory
6242
6244
revision = _get_one_revision('switch', revision)
6273
6275
possible_transports=possible_transports)
6274
6276
if revision is not None:
6275
6277
revision = revision.as_revision_id(to_branch)
6276
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)
6277
6280
if had_explicit_nick:
6278
6281
branch = control_dir.open_branch() #get the new branch!
6279
6282
branch.nick = to_branch.nick
6724
6727
('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6725
6728
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6726
6729
('cmd_conflicts', [], 'bzrlib.conflicts'),
6730
('cmd_ping', [], 'bzrlib.smart.ping'),
6727
6731
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6728
('cmd_verify_signatures', [],
6729
'bzrlib.commit_signature_commands'),
6732
('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
6730
6733
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6732
6735
builtin_command_registry.register_lazy(name, aliases, module_name)