2728
2717
class cmd_commit(Command):
2729
2718
"""Commit changes into a new revision.
2731
An explanatory message needs to be given for each commit. This is
2732
often done by using the --message option (getting the message from the
2733
command line) or by using the --file option (getting the message from
2734
a file). If neither of these options is given, an editor is opened for
2735
the user to enter the message. To see the changed files in the
2736
boilerplate text loaded into the editor, use the --show-diff option.
2738
By default, the entire tree is committed and the person doing the
2739
commit is assumed to be the author. These defaults can be overridden
2744
If selected files are specified, only changes to those files are
2745
committed. If a directory is specified then the directory and
2746
everything within it is committed.
2748
When excludes are given, they take precedence over selected files.
2749
For example, to commit only changes within foo, but not changes
2752
bzr commit foo -x foo/bar
2754
A selective commit after a merge is not yet supported.
2758
If the author of the change is not the same person as the committer,
2759
you can specify the author's name using the --author option. The
2760
name should be in the same format as a committer-id, e.g.
2761
"John Doe <jdoe@example.com>". If there is more than one author of
2762
the change you can specify the option multiple times, once for each
2767
A common mistake is to forget to add a new file or directory before
2768
running the commit command. The --strict option checks for unknown
2769
files and aborts the commit if any are found. More advanced pre-commit
2770
checks can be implemented by defining hooks. See ``bzr help hooks``
2775
If you accidentially commit the wrong changes or make a spelling
2776
mistake in the commit message say, you can use the uncommit command
2777
to undo it. See ``bzr help uncommit`` for details.
2779
Hooks can also be configured to run after a commit. This allows you
2780
to trigger updates to external systems like bug trackers. The --fixes
2781
option can be used to record the association between a revision and
2782
one or more bugs. See ``bzr help bugs`` for details.
2784
A selective commit may fail in some cases where the committed
2785
tree would be invalid. Consider::
2790
bzr commit foo -m "committing foo"
2791
bzr mv foo/bar foo/baz
2794
bzr commit foo/bar -m "committing bar but not baz"
2796
In the example above, the last commit will fail by design. This gives
2797
the user the opportunity to decide whether they want to commit the
2798
rename at the same time, separately first, or not at all. (As a general
2799
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2720
If no arguments are given, the entire tree is committed.
2722
If selected files are specified, only changes to those files are
2723
committed. If a directory is specified then the directory and everything
2724
within it is committed.
2726
When excludes are given, they take precedence over selected files.
2727
For example, too commit only changes within foo, but not changes within
2730
bzr commit foo -x foo/bar
2732
If author of the change is not the same person as the committer, you can
2733
specify the author's name using the --author option. The name should be
2734
in the same format as a committer-id, e.g. "John Doe <jdoe@example.com>".
2735
If there is more than one author of the change you can specify the option
2736
multiple times, once for each author.
2738
A selected-file commit may fail in some cases where the committed
2739
tree would be invalid. Consider::
2744
bzr commit foo -m "committing foo"
2745
bzr mv foo/bar foo/baz
2748
bzr commit foo/bar -m "committing bar but not baz"
2750
In the example above, the last commit will fail by design. This gives
2751
the user the opportunity to decide whether they want to commit the
2752
rename at the same time, separately first, or not at all. (As a general
2753
rule, when in doubt, Bazaar has a policy of Doing the Safe Thing.)
2755
Note: A selected-file commit after a merge is not yet supported.
2801
2757
# TODO: Run hooks on tree to-be-committed, and after commit.
4516
def run_smart_server(self, smart_server):
4517
"""Run 'smart_server' forever, with no UI output at all."""
4518
# For the duration of this server, no UI output is permitted. note
4519
# that this may cause problems with blackbox tests. This should be
4520
# changed with care though, as we dont want to use bandwidth sending
4521
# progress over stderr to smart server clients!
4522
from bzrlib import lockdir
4523
old_factory = ui.ui_factory
4524
old_lockdir_timeout = lockdir._DEFAULT_TIMEOUT_SECONDS
4526
ui.ui_factory = ui.SilentUIFactory()
4527
lockdir._DEFAULT_TIMEOUT_SECONDS = 0
4528
smart_server.serve()
4530
ui.ui_factory = old_factory
4531
lockdir._DEFAULT_TIMEOUT_SECONDS = old_lockdir_timeout
4564
4533
def get_host_and_port(self, port):
4565
4534
"""Return the host and port to run the smart server on.
4567
If 'port' is None, None will be returned for the host and port.
4536
If 'port' is None, the default host (`medium.BZR_DEFAULT_INTERFACE`)
4537
and port (`medium.BZR_DEFAULT_PORT`) will be used.
4569
4539
If 'port' has a colon in it, the string before the colon will be
4570
4540
interpreted as the host.
4573
4543
:return: A tuple of (host, port), where 'host' is a host name or IP,
4574
4544
and port is an integer TCP/IP port.
4577
if port is not None:
4546
from bzrlib.smart import medium
4547
host = medium.BZR_DEFAULT_INTERFACE
4549
port = medium.BZR_DEFAULT_PORT
4578
4551
if ':' in port:
4579
4552
host, port = port.split(':')
4580
4553
port = int(port)
4581
4554
return host, port
4583
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4585
from bzrlib.transport import get_transport, transport_server_registry
4556
def get_smart_server(self, transport, inet, port):
4557
"""Construct a smart server.
4559
:param transport: The base transport from which branches will be
4561
:param inet: If True, serve over stdin and stdout. Used for running
4563
:param port: The port to listen on. By default, it's `
4564
medium.BZR_DEFAULT_PORT`. See `get_host_and_port` for more
4566
:return: A smart server.
4568
from bzrlib.smart import medium, server
4570
smart_server = medium.SmartServerPipeStreamMedium(
4571
sys.stdin, sys.stdout, transport)
4573
host, port = self.get_host_and_port(port)
4574
smart_server = server.SmartTCPServer(
4575
transport, host=host, port=port)
4576
note('listening on port: %s' % smart_server.port)
4579
def run(self, port=None, inet=False, directory=None, allow_writes=False):
4580
from bzrlib.transport import get_transport
4581
from bzrlib.transport.chroot import ChrootServer
4586
4582
if directory is None:
4587
4583
directory = os.getcwd()
4588
if protocol is None:
4589
protocol = transport_server_registry.get()
4590
host, port = self.get_host_and_port(port)
4591
4584
url = urlutils.local_path_to_url(directory)
4592
4585
if not allow_writes:
4593
4586
url = 'readonly+' + url
4594
transport = get_transport(url)
4595
protocol(transport, host, port, inet)
4587
chroot_server = ChrootServer(get_transport(url))
4588
chroot_server.setUp()
4589
t = get_transport(chroot_server.get_url())
4590
smart_server = self.get_smart_server(t, inet, port)
4591
self.run_smart_server(smart_server)
4598
4594
class cmd_join(Command):
4846
4842
Option('body', help='Body for the email.', type=unicode),
4847
RegistryOption('format',
4848
help='Use the specified output format.',
4849
lazy_registry=('bzrlib.send', 'format_registry'))
4843
RegistryOption.from_kwargs('format',
4844
'Use the specified output format.',
4845
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4846
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4852
4849
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4853
4850
no_patch=False, revision=None, remember=False, output=None,
4854
format=None, mail_to=None, message=None, body=None, **kwargs):
4855
from bzrlib.send import send
4856
return send(submit_branch, revision, public_branch, remember,
4851
format='4', mail_to=None, message=None, body=None, **kwargs):
4852
return self._run(submit_branch, revision, public_branch, remember,
4857
4853
format, no_bundle, no_patch, output,
4858
kwargs.get('from', '.'), mail_to, message, body,
4854
kwargs.get('from', '.'), mail_to, message, body)
4856
def _run(self, submit_branch, revision, public_branch, remember, format,
4857
no_bundle, no_patch, output, from_, mail_to, message, body):
4858
from bzrlib.revision import NULL_REVISION
4859
branch = Branch.open_containing(from_)[0]
4861
outfile = cStringIO.StringIO()
4865
outfile = open(output, 'wb')
4866
# we may need to write data into branch's repository to calculate
4871
config = branch.get_config()
4873
mail_to = config.get_user_option('submit_to')
4874
mail_client = config.get_mail_client()
4875
if (not getattr(mail_client, 'supports_body', False)
4876
and body is not None):
4877
raise errors.BzrCommandError(
4878
'Mail client "%s" does not support specifying body' %
4879
mail_client.__class__.__name__)
4880
if remember and submit_branch is None:
4881
raise errors.BzrCommandError(
4882
'--remember requires a branch to be specified.')
4883
stored_submit_branch = branch.get_submit_branch()
4884
remembered_submit_branch = None
4885
if submit_branch is None:
4886
submit_branch = stored_submit_branch
4887
remembered_submit_branch = "submit"
4889
if stored_submit_branch is None or remember:
4890
branch.set_submit_branch(submit_branch)
4891
if submit_branch is None:
4892
submit_branch = branch.get_parent()
4893
remembered_submit_branch = "parent"
4894
if submit_branch is None:
4895
raise errors.BzrCommandError('No submit branch known or'
4897
if remembered_submit_branch is not None:
4898
note('Using saved %s location "%s" to determine what '
4899
'changes to submit.', remembered_submit_branch,
4903
submit_config = Branch.open(submit_branch).get_config()
4904
mail_to = submit_config.get_user_option("child_submit_to")
4906
stored_public_branch = branch.get_public_branch()
4907
if public_branch is None:
4908
public_branch = stored_public_branch
4909
elif stored_public_branch is None or remember:
4910
branch.set_public_branch(public_branch)
4911
if no_bundle and public_branch is None:
4912
raise errors.BzrCommandError('No public branch specified or'
4914
base_revision_id = None
4916
if revision is not None:
4917
if len(revision) > 2:
4918
raise errors.BzrCommandError('bzr send takes '
4919
'at most two one revision identifiers')
4920
revision_id = revision[-1].as_revision_id(branch)
4921
if len(revision) == 2:
4922
base_revision_id = revision[0].as_revision_id(branch)
4923
if revision_id is None:
4924
revision_id = branch.last_revision()
4925
if revision_id == NULL_REVISION:
4926
raise errors.BzrCommandError('No revisions to submit.')
4928
directive = merge_directive.MergeDirective2.from_objects(
4929
branch.repository, revision_id, time.time(),
4930
osutils.local_time_offset(), submit_branch,
4931
public_branch=public_branch, include_patch=not no_patch,
4932
include_bundle=not no_bundle, message=message,
4933
base_revision_id=base_revision_id)
4934
elif format == '0.9':
4937
patch_type = 'bundle'
4939
raise errors.BzrCommandError('Format 0.9 does not'
4940
' permit bundle with no patch')
4946
directive = merge_directive.MergeDirective.from_objects(
4947
branch.repository, revision_id, time.time(),
4948
osutils.local_time_offset(), submit_branch,
4949
public_branch=public_branch, patch_type=patch_type,
4952
outfile.writelines(directive.to_lines())
4954
subject = '[MERGE] '
4955
if message is not None:
4958
revision = branch.repository.get_revision(revision_id)
4959
subject += revision.get_summary()
4960
basename = directive.get_disk_name(branch)
4961
mail_client.compose_merge_request(mail_to, subject,
4862
4970
class cmd_bundle_revisions(cmd_send):
4863
4972
"""Create a merge-directive for submitting changes.
4865
4974
A merge directive provides many things needed for requesting merges:
5167
5268
from bzrlib import switch
5168
5269
tree_location = '.'
5169
5270
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5171
branch = control_dir.open_branch()
5172
had_explicit_nick = branch.get_config().has_explicit_nickname()
5173
except errors.NotBranchError:
5174
had_explicit_nick = False
5271
branch = control_dir.open_branch()
5176
5273
to_branch = Branch.open(to_location)
5177
5274
except errors.NotBranchError:
5178
this_url = self._get_branch_location(control_dir)
5275
this_branch = control_dir.open_branch()
5276
# This may be a heavy checkout, where we want the master branch
5277
this_url = this_branch.get_bound_location()
5278
# If not, use a local sibling
5279
if this_url is None:
5280
this_url = this_branch.base
5179
5281
to_branch = Branch.open(
5180
5282
urlutils.join(this_url, '..', to_location))
5181
5283
switch.switch(control_dir, to_branch, force)
5182
if had_explicit_nick:
5284
if branch.get_config().has_explicit_nickname():
5183
5285
branch = control_dir.open_branch() #get the new branch!
5184
5286
branch.nick = to_branch.nick
5185
5287
note('Switched to branch: %s',
5186
5288
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
5188
def _get_branch_location(self, control_dir):
5189
"""Return location of branch for this control dir."""
5191
this_branch = control_dir.open_branch()
5192
# This may be a heavy checkout, where we want the master branch
5193
master_location = this_branch.get_bound_location()
5194
if master_location is not None:
5195
return master_location
5196
# If not, use a local sibling
5197
return this_branch.base
5198
except errors.NotBranchError:
5199
format = control_dir.find_branch_format()
5200
if getattr(format, 'get_reference', None) is not None:
5201
return format.get_reference(control_dir)
5203
return control_dir.root_transport.base
5206
5291
class cmd_view(Command):
5207
5292
"""Manage filtered views.