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."""
4718
4730
class cmd_revert(Command):
4719
__doc__ = """Revert files to a previous revision.
4732
Set files in the working tree back to the contents of a previous revision.
4721
4734
Giving a list of files will revert only those files. Otherwise, all files
4722
4735
will be reverted. If the revision is not specified with '--revision', the
4723
last committed revision is used.
4736
working tree basis revision is used. A revert operation affects only the
4737
working tree, not any revision history like the branch and repository or
4738
the working tree basis revision.
4725
4740
To remove only some changes, without reverting to a prior version, use
4726
4741
merge instead. For example, "merge . -r -2..-3" (don't forget the ".")
4727
4742
will remove the changes introduced by the second last commit (-2), without
4728
4743
affecting the changes introduced by the last commit (-1). To remove
4729
4744
certain changes on a hunk-by-hunk basis, see the shelve command.
4745
To update the branch to a specific revision or the latest revision and
4746
update the working tree accordingly while preserving local changes, see the
4731
By default, any files that have been manually changed will be backed up
4732
first. (Files changed only by merge are not backed up.) Backup files have
4733
'.~#~' appended to their name, where # is a number.
4749
Uncommitted changes to files that are reverted will be discarded.
4750
Howver, by default, any files that have been manually changed will be
4751
backed up first. (Files changed only by merge are not backed up.) Backup
4752
files have '.~#~' appended to their name, where # is a number.
4735
4754
When you provide files, you can use their current pathname or the pathname
4736
4755
from the target revision. So you can use revert to "undelete" a file by
5479
5498
help="Protocol to serve.",
5480
5499
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5481
5500
value_switches=True),
5502
help='Listen for connections on nominated address.', type=str),
5483
help='Listen for connections on nominated port of the form '
5484
'[hostname:]portnumber. Passing 0 as the port number will '
5485
'result in a dynamically allocated port. The default port '
5486
'depends on the protocol.',
5504
help='Listen for connections on nominated port. Passing 0 as '
5505
'the port number will result in a dynamically allocated '
5506
'port. The default port depends on the protocol.',
5488
5508
custom_help('directory',
5489
5509
help='Serve contents of this directory.'),
5490
5510
Option('allow-writes',
5500
5520
help='Override the default idle client timeout (5min).'),
5503
def get_host_and_port(self, port):
5504
"""Return the host and port to run the smart server on.
5506
If 'port' is None, None will be returned for the host and port.
5508
If 'port' has a colon in it, the string before the colon will be
5509
interpreted as the host.
5511
:param port: A string of the port to run the server on.
5512
:return: A tuple of (host, port), where 'host' is a host name or IP,
5513
and port is an integer TCP/IP port.
5516
if port is not None:
5518
host, port = port.split(':')
5522
def run(self, port=None, inet=False, directory=None, allow_writes=False,
5523
protocol=None, client_timeout=None):
5523
def run(self, listen=None, port=None, inet=False, directory=None,
5524
allow_writes=False, protocol=None, client_timeout=None):
5524
5525
from bzrlib import transport
5525
5526
if directory is None:
5526
5527
directory = os.getcwd()
5527
5528
if protocol is None:
5528
5529
protocol = transport.transport_server_registry.get()
5529
host, port = self.get_host_and_port(port)
5530
5530
url = transport.location_to_url(directory)
5531
5531
if not allow_writes:
5532
5532
url = 'readonly+' + url
5533
5533
t = transport.get_transport_from_url(url)
5535
protocol(t, host, port, inet, client_timeout)
5536
except TypeError, e:
5537
# We use symbol_versioning.deprecated_in just so that people
5538
# grepping can find it here.
5539
# symbol_versioning.deprecated_in((2, 5, 0))
5540
symbol_versioning.warn(
5541
'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5542
'Most likely it needs to be updated to support a'
5543
' "timeout" parameter (added in bzr 2.5.0)'
5544
% (e, protocol.__module__, protocol),
5546
protocol(t, host, port, inet)
5534
protocol(t, listen, port, inet, client_timeout)
5549
5537
class cmd_join(Command):
6251
6239
possible_transports=possible_transports,
6252
6240
source_branch=branch).open_branch()
6254
to_branch = lookup_sibling_branch(control_dir, to_location)
6243
to_branch = Branch.open(to_location,
6244
possible_transports=possible_transports)
6245
except errors.NotBranchError:
6246
to_branch = open_sibling_branch(control_dir, to_location,
6247
possible_transports=possible_transports)
6255
6248
if revision is not None:
6256
6249
revision = revision.as_revision_id(to_branch)
6257
6250
switch.switch(control_dir, to_branch, force, revision_id=revision)
6455
6448
takes_args = ["location?"]
6450
takes_options = ['directory',
6451
Option('force', help='Remove branch even if it is the active branch.')]
6457
6453
aliases = ["rmbranch"]
6459
def run(self, location=None):
6460
if location is None:
6462
cdir = controldir.ControlDir.open_containing(location)[0]
6463
cdir.destroy_branch()
6455
def run(self, directory=None, location=None, force=False):
6456
br = open_nearby_branch(near=directory, location=location)
6457
if not force and br.bzrdir.has_workingtree():
6459
active_branch = br.bzrdir.open_branch(name="")
6460
except errors.NotBranchError:
6461
active_branch = None
6462
if (active_branch is not None and
6463
br.control_url == active_branch.control_url):
6464
raise errors.BzrCommandError(
6465
gettext("Branch is active. Use --force to remove it."))
6466
br.bzrdir.destroy_branch(br.name)
6466
6469
class cmd_shelve(Command):
6696
6699
('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6697
6700
('cmd_conflicts', [], 'bzrlib.conflicts'),
6698
6701
('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6699
('cmd_verify_signatures', [],
6700
'bzrlib.commit_signature_commands'),
6702
('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
6701
6703
('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6703
6705
builtin_command_registry.register_lazy(name, aliases, module_name)