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_config = Branch.open(submit_branch).get_config()
4902
mail_to = submit_config.get_user_option("child_submit_to")
4904
format = submit_config.get_user_option("child_submit_format")
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.')
4930
directive = merge_directive.MergeDirective2.from_objects(
4931
branch.repository, revision_id, time.time(),
4932
osutils.local_time_offset(), submit_branch,
4933
public_branch=public_branch, include_patch=not no_patch,
4934
include_bundle=not no_bundle, message=message,
4935
base_revision_id=base_revision_id)
4936
elif format == '0.9':
4939
patch_type = 'bundle'
4941
raise errors.BzrCommandError('Format 0.9 does not'
4942
' permit bundle with no patch')
4948
directive = merge_directive.MergeDirective.from_objects(
4949
branch.repository, revision_id, time.time(),
4950
osutils.local_time_offset(), submit_branch,
4951
public_branch=public_branch, patch_type=patch_type,
4954
raise errors.BzrCommandError("No such send format '%s'." %
4958
directive.compose_merge_request(mail_client, mail_to, body,
4964
outfile = open(output, 'wb')
4966
outfile.writelines(directive.to_lines())
4968
if outfile is not self.outf:
4859
kwargs.get('from', '.'), mail_to, message, body,
4974
4863
class cmd_bundle_revisions(cmd_send):
4976
4864
"""Create a merge-directive for submitting changes.
4978
4866
A merge directive provides many things needed for requesting merges:
5145
5034
graph = branch.repository.get_graph()
5146
5035
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5147
5036
revid1, revid2 = rev1.rev_id, rev2.rev_id
5148
5037
# only show revisions between revid1 and revid2 (inclusive)
5149
5038
tags = [(tag, revid) for tag, revid in tags if
5150
5039
graph.is_between(revid, revid1, revid2)]
5155
elif sort == 'time':
5157
for tag, revid in tags:
5159
revobj = branch.repository.get_revision(revid)
5160
except errors.NoSuchRevision:
5161
timestamp = sys.maxint # place them at the end
5163
timestamp = revobj.timestamp
5164
timestamps[revid] = timestamp
5165
tags.sort(key=lambda x: timestamps[x[1]])
5167
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5168
revno_map = branch.get_revision_id_to_revno_map()
5169
tags = [ (tag, '.'.join(map(str, revno_map.get(revid, ('?',)))))
5170
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)
5171
5067
for tag, revspec in tags:
5172
5068
self.outf.write('%-20s %s\n' % (tag, revspec))