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