81
81
def tree_files_for_add(file_list):
82
"""Add handles files a bit differently so it a custom implementation."""
83
Return a tree and list of absolute paths from a file list.
85
Similar to tree_files, but add handles files a bit differently, so it a
86
custom implementation. In particular, MutableTreeTree.smart_add expects
87
absolute paths, which it immediately converts to relative paths.
89
# FIXME Would be nice to just return the relative paths like
90
# internal_tree_files does, but there are a large number of unit tests
91
# that assume the current interface to mutabletree.smart_add
84
tree = WorkingTree.open_containing(file_list[0])[0]
93
tree, relpath = WorkingTree.open_containing(file_list[0])
85
94
if tree.supports_views():
86
95
view_files = tree.views.lookup_view()
88
97
for filename in file_list:
89
98
if not osutils.is_inside_any(view_files, filename):
90
99
raise errors.FileOutsideView(filename, view_files)
100
file_list = file_list[:]
101
file_list[0] = tree.abspath(relpath)
92
103
tree = WorkingTree.open_containing(u'.')[0]
93
104
if tree.supports_views():
2696
2727
class cmd_commit(Command):
2697
2728
"""Commit changes into a new revision.
2699
If no arguments are given, the entire tree is committed.
2701
If selected files are specified, only changes to those files are
2702
committed. If a directory is specified then the directory and everything
2703
within it is committed.
2705
When excludes are given, they take precedence over selected files.
2706
For example, too commit only changes within foo, but not changes within
2709
bzr commit foo -x foo/bar
2711
If author of the change is not the same person as the committer, you can
2712
specify the author's name using the --author option. The name should be
2713
in the same format as a committer-id, e.g. "John Doe <jdoe@example.com>".
2714
If there is more than one author of the change you can specify the option
2715
multiple times, once for each author.
2717
A selected-file commit may fail in some cases where the committed
2718
tree would be invalid. Consider::
2723
bzr commit foo -m "committing foo"
2724
bzr mv foo/bar foo/baz
2727
bzr commit foo/bar -m "committing bar but not baz"
2729
In the example above, the last commit will fail by design. This gives
2730
the user the opportunity to decide whether they want to commit the
2731
rename at the same time, separately first, or not at all. (As a general
2732
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2734
Note: A selected-file commit after a merge is not yet supported.
2730
An explanatory message needs to be given for each commit. This is
2731
often done by using the --message option (getting the message from the
2732
command line) or by using the --file option (getting the message from
2733
a file). If neither of these options is given, an editor is opened for
2734
the user to enter the message. To see the changed files in the
2735
boilerplate text loaded into the editor, use the --show-diff option.
2737
By default, the entire tree is committed and the person doing the
2738
commit is assumed to be the author. These defaults can be overridden
2743
If selected files are specified, only changes to those files are
2744
committed. If a directory is specified then the directory and
2745
everything within it is committed.
2747
When excludes are given, they take precedence over selected files.
2748
For example, to commit only changes within foo, but not changes
2751
bzr commit foo -x foo/bar
2753
A selective commit after a merge is not yet supported.
2757
If the author of the change is not the same person as the committer,
2758
you can specify the author's name using the --author option. The
2759
name should be in the same format as a committer-id, e.g.
2760
"John Doe <jdoe@example.com>". If there is more than one author of
2761
the change you can specify the option multiple times, once for each
2766
A common mistake is to forget to add a new file or directory before
2767
running the commit command. The --strict option checks for unknown
2768
files and aborts the commit if any are found. More advanced pre-commit
2769
checks can be implemented by defining hooks. See ``bzr help hooks``
2774
If you accidentially commit the wrong changes or make a spelling
2775
mistake in the commit message say, you can use the uncommit command
2776
to undo it. See ``bzr help uncommit`` for details.
2778
Hooks can also be configured to run after a commit. This allows you
2779
to trigger updates to external systems like bug trackers. The --fixes
2780
option can be used to record the association between a revision and
2781
one or more bugs. See ``bzr help bugs`` for details.
2783
A selective commit may fail in some cases where the committed
2784
tree would be invalid. Consider::
2789
bzr commit foo -m "committing foo"
2790
bzr mv foo/bar foo/baz
2793
bzr commit foo/bar -m "committing bar but not baz"
2795
In the example above, the last commit will fail by design. This gives
2796
the user the opportunity to decide whether they want to commit the
2797
rename at the same time, separately first, or not at all. (As a general
2798
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2736
2800
# TODO: Run hooks on tree to-be-committed, and after commit.
4488
4540
takes_options = [
4490
4542
help='Serve on stdin/out for use from inetd or sshd.'),
4543
RegistryOption('protocol',
4544
help="Protocol to serve.",
4545
lazy_registry=('bzrlib.transport', 'transport_server_registry'),
4546
value_switches=True),
4492
4548
help='Listen for connections on nominated port of the form '
4493
4549
'[hostname:]portnumber. Passing 0 as the port number will '
4494
'result in a dynamically allocated port. The default port is '
4550
'result in a dynamically allocated port. The default port '
4551
'depends on the protocol.',
4497
4553
Option('directory',
4498
4554
help='Serve contents of this directory.',
4507
def run_smart_server(self, smart_server):
4508
"""Run 'smart_server' forever, with no UI output at all."""
4509
# For the duration of this server, no UI output is permitted. note
4510
# that this may cause problems with blackbox tests. This should be
4511
# changed with care though, as we dont want to use bandwidth sending
4512
# progress over stderr to smart server clients!
4513
from bzrlib import lockdir
4514
old_factory = ui.ui_factory
4515
old_lockdir_timeout = lockdir._DEFAULT_TIMEOUT_SECONDS
4517
ui.ui_factory = ui.SilentUIFactory()
4518
lockdir._DEFAULT_TIMEOUT_SECONDS = 0
4519
smart_server.serve()
4521
ui.ui_factory = old_factory
4522
lockdir._DEFAULT_TIMEOUT_SECONDS = old_lockdir_timeout
4524
4563
def get_host_and_port(self, port):
4525
4564
"""Return the host and port to run the smart server on.
4527
If 'port' is None, the default host (`medium.BZR_DEFAULT_INTERFACE`)
4528
and port (`medium.BZR_DEFAULT_PORT`) will be used.
4566
If 'port' is None, None will be returned for the host and port.
4530
4568
If 'port' has a colon in it, the string before the colon will be
4531
4569
interpreted as the host.
4534
4572
:return: A tuple of (host, port), where 'host' is a host name or IP,
4535
4573
and port is an integer TCP/IP port.
4537
from bzrlib.smart import medium
4538
host = medium.BZR_DEFAULT_INTERFACE
4540
port = medium.BZR_DEFAULT_PORT
4576
if port is not None:
4542
4577
if ':' in port:
4543
4578
host, port = port.split(':')
4544
4579
port = int(port)
4545
4580
return host, port
4547
def get_smart_server(self, transport, inet, port):
4548
"""Construct a smart server.
4550
:param transport: The base transport from which branches will be
4552
:param inet: If True, serve over stdin and stdout. Used for running
4554
:param port: The port to listen on. By default, it's `
4555
medium.BZR_DEFAULT_PORT`. See `get_host_and_port` for more
4557
:return: A smart server.
4559
from bzrlib.smart import medium, server
4561
smart_server = medium.SmartServerPipeStreamMedium(
4562
sys.stdin, sys.stdout, transport)
4564
host, port = self.get_host_and_port(port)
4565
smart_server = server.SmartTCPServer(
4566
transport, host=host, port=port)
4567
note('listening on port: %s' % smart_server.port)
4570
def run(self, port=None, inet=False, directory=None, allow_writes=False):
4571
from bzrlib.transport import get_transport
4572
from bzrlib.transport.chroot import ChrootServer
4582
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4584
from bzrlib.transport import get_transport, transport_server_registry
4573
4585
if directory is None:
4574
4586
directory = os.getcwd()
4587
if protocol is None:
4588
protocol = transport_server_registry.get()
4589
host, port = self.get_host_and_port(port)
4575
4590
url = urlutils.local_path_to_url(directory)
4576
4591
if not allow_writes:
4577
4592
url = 'readonly+' + url
4578
chroot_server = ChrootServer(get_transport(url))
4579
chroot_server.setUp()
4580
t = get_transport(chroot_server.get_url())
4581
smart_server = self.get_smart_server(t, inet, port)
4582
self.run_smart_server(smart_server)
4593
transport = get_transport(url)
4594
protocol(transport, host, port, inet)
4585
4597
class cmd_join(Command):
4840
4852
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4841
4853
no_patch=False, revision=None, remember=False, output=None,
4842
format='4', mail_to=None, message=None, body=None, **kwargs):
4854
format=None, mail_to=None, message=None, body=None, **kwargs):
4843
4855
return self._run(submit_branch, revision, public_branch, remember,
4844
4856
format, no_bundle, no_patch, output,
4845
4857
kwargs.get('from', '.'), mail_to, message, body)
4847
4859
def _run(self, submit_branch, revision, public_branch, remember, format,
4848
4860
no_bundle, no_patch, output, from_, mail_to, message, body):
4849
4861
from bzrlib.revision import NULL_REVISION
4850
branch = Branch.open_containing(from_)[0]
4852
outfile = cStringIO.StringIO()
4856
outfile = open(output, 'wb')
4862
tree, branch = bzrdir.BzrDir.open_containing_tree_or_branch(from_)[:2]
4857
4863
# we may need to write data into branch's repository to calculate
4858
4864
# the data to send.
4859
4865
branch.lock_write()
4939
4951
osutils.local_time_offset(), submit_branch,
4940
4952
public_branch=public_branch, patch_type=patch_type,
4941
4953
message=message)
4955
raise errors.BzrCommandError("No such send format '%s'." %
4943
outfile.writelines(directive.to_lines())
4944
4958
if output is None:
4945
subject = '[MERGE] '
4946
if message is not None:
4959
directive.compose_merge_request(mail_client, mail_to, body,
4949
revision = branch.repository.get_revision(revision_id)
4950
subject += revision.get_summary()
4951
basename = directive.get_disk_name(branch)
4952
mail_client.compose_merge_request(mail_to, subject,
4965
outfile = open(output, 'wb')
4967
outfile.writelines(directive.to_lines())
4969
if outfile is not self.outf:
4958
4972
branch.unlock()
5259
5273
from bzrlib import switch
5260
5274
tree_location = '.'
5261
5275
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5262
branch = control_dir.open_branch()
5277
branch = control_dir.open_branch()
5278
had_explicit_nick = branch.get_config().has_explicit_nickname()
5279
except errors.NotBranchError:
5280
had_explicit_nick = False
5264
5282
to_branch = Branch.open(to_location)
5265
5283
except errors.NotBranchError:
5266
this_branch = control_dir.open_branch()
5267
# This may be a heavy checkout, where we want the master branch
5268
this_url = this_branch.get_bound_location()
5269
# If not, use a local sibling
5270
if this_url is None:
5271
this_url = this_branch.base
5284
this_url = self._get_branch_location(control_dir)
5272
5285
to_branch = Branch.open(
5273
5286
urlutils.join(this_url, '..', to_location))
5274
5287
switch.switch(control_dir, to_branch, force)
5275
if branch.get_config().has_explicit_nickname():
5288
if had_explicit_nick:
5276
5289
branch = control_dir.open_branch() #get the new branch!
5277
5290
branch.nick = to_branch.nick
5278
5291
note('Switched to branch: %s',
5279
5292
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5294
def _get_branch_location(self, control_dir):
5295
"""Return location of branch for this control dir."""
5297
this_branch = control_dir.open_branch()
5298
# This may be a heavy checkout, where we want the master branch
5299
master_location = this_branch.get_bound_location()
5300
if master_location is not None:
5301
return master_location
5302
# If not, use a local sibling
5303
return this_branch.base
5304
except errors.NotBranchError:
5305
format = control_dir.find_branch_format()
5306
if getattr(format, 'get_reference', None) is not None:
5307
return format.get_reference(control_dir)
5309
return control_dir.root_transport.base
5282
5312
class cmd_view(Command):
5283
5313
"""Manage filtered views.
5585
5615
dry_run=dry_run, no_prompt=force)
5588
def _create_prefix(cur_transport):
5589
needed = [cur_transport]
5590
# Recurse upwards until we can create a directory successfully
5592
new_transport = cur_transport.clone('..')
5593
if new_transport.base == cur_transport.base:
5594
raise errors.BzrCommandError(
5595
"Failed to create path prefix for %s."
5596
% cur_transport.base)
5598
new_transport.mkdir('.')
5599
except errors.NoSuchFile:
5600
needed.append(new_transport)
5601
cur_transport = new_transport
5618
class cmd_reference(Command):
5619
"""list, view and set branch locations for nested trees.
5621
If no arguments are provided, lists the branch locations for nested trees.
5622
If one argument is provided, display the branch location for that tree.
5623
If two arguments are provided, set the branch location for that tree.
5628
takes_args = ['path?', 'location?']
5630
def run(self, path=None, location=None):
5632
if path is not None:
5634
tree, branch, relpath =(
5635
bzrdir.BzrDir.open_containing_tree_or_branch(branchdir))
5636
if path is not None:
5639
tree = branch.basis_tree()
5641
info = branch._get_all_reference_info().iteritems()
5642
self._display_reference_info(tree, branch, info)
5604
# Now we only need to create child directories
5606
cur_transport = needed.pop()
5607
cur_transport.ensure_base()
5644
file_id = tree.path2id(path)
5646
raise errors.NotVersionedError(path)
5647
if location is None:
5648
info = [(file_id, branch.get_reference_info(file_id))]
5649
self._display_reference_info(tree, branch, info)
5651
branch.set_reference_info(file_id, path, location)
5653
def _display_reference_info(self, tree, branch, info):
5655
for file_id, (path, location) in info:
5657
path = tree.id2path(file_id)
5658
except errors.NoSuchId:
5660
ref_list.append((path, location))
5661
for path, location in sorted(ref_list):
5662
self.outf.write('%s %s\n' % (path, location))
5610
5665
# these get imported and then picked up by the scan for cmd_*