4845
4847
Option('body', help='Body for the email.', type=unicode),
4846
RegistryOption.from_kwargs('format',
4847
'Use the specified output format.',
4848
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4849
'0.9': 'Bundle format 0.9, Merge Directive 1',})
4848
RegistryOption('format',
4849
help='Use the specified output format.',
4850
lazy_registry=('bzrlib.send', 'format_registry'))
4852
4853
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4853
4854
no_patch=False, revision=None, remember=False, output=None,
4854
4855
format=None, mail_to=None, message=None, body=None, **kwargs):
4855
return self._run(submit_branch, revision, public_branch, remember,
4856
from bzrlib.send import send
4857
return send(submit_branch, revision, public_branch, remember,
4856
4858
format, no_bundle, no_patch, output,
4857
kwargs.get('from', '.'), mail_to, message, body)
4859
def _run(self, submit_branch, revision, public_branch, remember, format,
4860
no_bundle, no_patch, output, from_, mail_to, message, body):
4861
from bzrlib.revision import NULL_REVISION
4862
tree, branch = bzrdir.BzrDir.open_containing_tree_or_branch(from_)[:2]
4863
# we may need to write data into branch's repository to calculate
4868
config = branch.get_config()
4870
mail_to = config.get_user_option('submit_to')
4871
mail_client = config.get_mail_client()
4872
if (not getattr(mail_client, 'supports_body', False)
4873
and body is not None):
4874
raise errors.BzrCommandError(
4875
'Mail client "%s" does not support specifying body' %
4876
mail_client.__class__.__name__)
4877
if remember and submit_branch is None:
4878
raise errors.BzrCommandError(
4879
'--remember requires a branch to be specified.')
4880
stored_submit_branch = branch.get_submit_branch()
4881
remembered_submit_branch = None
4882
if submit_branch is None:
4883
submit_branch = stored_submit_branch
4884
remembered_submit_branch = "submit"
4886
if stored_submit_branch is None or remember:
4887
branch.set_submit_branch(submit_branch)
4888
if submit_branch is None:
4889
submit_branch = branch.get_parent()
4890
remembered_submit_branch = "parent"
4891
if submit_branch is None:
4892
raise errors.BzrCommandError('No submit branch known or'
4894
if remembered_submit_branch is not None:
4895
note('Using saved %s location "%s" to determine what '
4896
'changes to submit.', remembered_submit_branch,
4899
if mail_to is None or format is None:
4900
submit_br = Branch.open(submit_branch)
4901
submit_config = submit_br.get_config()
4903
mail_to = submit_config.get_user_option("child_submit_to")
4905
format = submit_br.get_child_submit_format()
4907
stored_public_branch = branch.get_public_branch()
4908
if public_branch is None:
4909
public_branch = stored_public_branch
4910
elif stored_public_branch is None or remember:
4911
branch.set_public_branch(public_branch)
4912
if no_bundle and public_branch is None:
4913
raise errors.BzrCommandError('No public branch specified or'
4915
base_revision_id = None
4917
if revision is not None:
4918
if len(revision) > 2:
4919
raise errors.BzrCommandError('bzr send takes '
4920
'at most two one revision identifiers')
4921
revision_id = revision[-1].as_revision_id(branch)
4922
if len(revision) == 2:
4923
base_revision_id = revision[0].as_revision_id(branch)
4924
if revision_id is None:
4925
revision_id = branch.last_revision()
4926
if revision_id == NULL_REVISION:
4927
raise errors.BzrCommandError('No revisions to submit.')
4931
directive = merge_directive.MergeDirective2.from_objects(
4932
branch.repository, revision_id, time.time(),
4933
osutils.local_time_offset(), submit_branch,
4934
public_branch=public_branch, include_patch=not no_patch,
4935
include_bundle=not no_bundle, message=message,
4936
base_revision_id=base_revision_id)
4937
elif format == '0.9':
4940
patch_type = 'bundle'
4942
raise errors.BzrCommandError('Format 0.9 does not'
4943
' permit bundle with no patch')
4949
directive = merge_directive.MergeDirective.from_objects(
4950
branch.repository, revision_id, time.time(),
4951
osutils.local_time_offset(), submit_branch,
4952
public_branch=public_branch, patch_type=patch_type,
4955
raise errors.BzrCommandError("No such send format '%s'." %
4959
directive.compose_merge_request(mail_client, mail_to, body,
4965
outfile = open(output, 'wb')
4967
outfile.writelines(directive.to_lines())
4969
if outfile is not self.outf:
4859
kwargs.get('from', '.'), mail_to, message, body,
4975
4863
class cmd_bundle_revisions(cmd_send):
4977
4864
"""Create a merge-directive for submitting changes.
4979
4866
A merge directive provides many things needed for requesting merges:
5146
5034
graph = branch.repository.get_graph()
5147
5035
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5148
5036
revid1, revid2 = rev1.rev_id, rev2.rev_id
5149
5037
# only show revisions between revid1 and revid2 (inclusive)
5150
5038
tags = [(tag, revid) for tag, revid in tags if
5151
5039
graph.is_between(revid, revid1, revid2)]
5156
elif sort == 'time':
5158
for tag, revid in tags:
5160
revobj = branch.repository.get_revision(revid)
5161
except errors.NoSuchRevision:
5162
timestamp = sys.maxint # place them at the end
5164
timestamp = revobj.timestamp
5165
timestamps[revid] = timestamp
5166
tags.sort(key=lambda x: timestamps[x[1]])
5168
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5169
revno_map = branch.get_revision_id_to_revno_map()
5170
tags = [ (tag, '.'.join(map(str, revno_map.get(revid, ('?',)))))
5171
for tag, revid in tags ]
5042
elif sort == 'time':
5044
for tag, revid in tags:
5046
revobj = branch.repository.get_revision(revid)
5047
except errors.NoSuchRevision:
5048
timestamp = sys.maxint # place them at the end
5050
timestamp = revobj.timestamp
5051
timestamps[revid] = timestamp
5052
tags.sort(key=lambda x: timestamps[x[1]])
5054
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5055
for index, (tag, revid) in enumerate(tags):
5057
revno = branch.revision_id_to_dotted_revno(revid)
5058
if isinstance(revno, tuple):
5059
revno = '.'.join(map(str, revno))
5060
except errors.NoSuchRevision:
5061
# Bad tag data/merges can lead to tagged revisions
5062
# which are not in this branch. Fail gracefully ...
5064
tags[index] = (tag, revno)
5172
5067
for tag, revspec in tags:
5173
5068
self.outf.write('%-20s %s\n' % (tag, revspec))