38
from bzrlib.revision import (
36
43
format_registry = registry.Registry()
39
class cmd_send(Command):
40
"""Mail or create a merge-directive for submitting changes.
42
A merge directive provides many things needed for requesting merges:
44
* A machine-readable description of the merge to perform
46
* An optional patch that is a preview of the changes requested
48
* An optional bundle of revision data, so that the changes can be applied
49
directly from the merge directive, without retrieving data from a
52
If --no-bundle is specified, then public_branch is needed (and must be
53
up-to-date), so that the receiver can perform the merge using the
54
public_branch. The public_branch is always included if known, so that
55
people can check it later.
57
The submit branch defaults to the parent, but can be overridden. Both
58
submit branch and public branch will be remembered if supplied.
60
If a public_branch is known for the submit_branch, that public submit
61
branch is used in the merge instructions. This means that a local mirror
62
can be used as your actual submit branch, once you have set public_branch
65
Mail is sent using your preferred mail program. This should be transparent
66
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
67
If the preferred client can't be found (or used), your editor will be used.
69
To use a specific mail program, set the mail_client configuration option.
70
(For Thunderbird 1.5, this works around some bugs.) Supported values for
71
specific clients are "claws", "evolution", "kmail", "mutt", and
72
"thunderbird"; generic options are "default", "editor", "emacsclient",
73
"mapi", and "xdg-email". Plugins may also add supported clients.
75
If mail is being sent, a to address is required. This can be supplied
76
either on the commandline, by setting the submit_to configuration
77
option in the branch itself or the child_submit_to configuration option
80
Two formats are currently supported: "4" uses revision bundle format 4 and
81
merge directive format 2. It is significantly faster and smaller than
82
older formats. It is compatible with Bazaar 0.19 and later. It is the
83
default. "0.9" uses revision bundle format 0.9 and merge directive
84
format 1. It is compatible with Bazaar 0.12 - 0.18.
86
The merge directives created by bzr send may be applied using bzr merge or
87
bzr pull by specifying a file containing a merge directive as the location.
90
encoding_type = 'exact'
92
_see_also = ['merge', 'pull']
94
takes_args = ['submit_branch?', 'public_branch?']
98
help='Do not include a bundle in the merge directive.'),
99
Option('no-patch', help='Do not include a preview patch in the merge'
102
help='Remember submit and public branch.'),
104
help='Branch to generate the submission from, '
105
'rather than the one containing the working directory.',
108
Option('output', short_name='o',
109
help='Write merge directive to this file; '
112
Option('mail-to', help='Mail the request to this address.',
116
Option('body', help='Body for the email.', type=unicode),
117
RegistryOption('format',
118
help='Use the specified output format.',
119
registry=format_registry)
122
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
123
no_patch=False, revision=None, remember=False, output=None,
124
format=None, mail_to=None, message=None, body=None, **kwargs):
125
return self._run(submit_branch, revision, public_branch, remember,
126
format, no_bundle, no_patch, output,
127
kwargs.get('from', '.'), mail_to, message, body)
129
def _run(self, submit_branch, revision, public_branch, remember, format,
130
no_bundle, no_patch, output, from_, mail_to, message, body):
131
from bzrlib import bzrdir
132
from bzrlib.branch import Branch
133
from bzrlib.revision import NULL_REVISION
134
tree, branch = bzrdir.BzrDir.open_containing_tree_or_branch(from_)[:2]
135
# we may need to write data into branch's repository to calculate
140
config = branch.get_config()
142
mail_to = config.get_user_option('submit_to')
143
mail_client = config.get_mail_client()
144
if (not getattr(mail_client, 'supports_body', False)
145
and body is not None):
146
raise errors.BzrCommandError(
147
'Mail client "%s" does not support specifying body' %
148
mail_client.__class__.__name__)
149
if remember and submit_branch is None:
46
def send(submit_branch, revision, public_branch, remember, format,
47
no_bundle, no_patch, output, from_, mail_to, message, body,
49
tree, branch = bzrdir.BzrDir.open_containing_tree_or_branch(from_)[:2]
50
# we may need to write data into branch's repository to calculate
55
config = branch.get_config()
57
mail_to = config.get_user_option('submit_to')
58
mail_client = config.get_mail_client()
59
if (not getattr(mail_client, 'supports_body', False)
60
and body is not None):
150
61
raise errors.BzrCommandError(
151
'--remember requires a branch to be specified.')
152
stored_submit_branch = branch.get_submit_branch()
153
remembered_submit_branch = None
154
if submit_branch is None:
155
submit_branch = stored_submit_branch
156
remembered_submit_branch = "submit"
158
if stored_submit_branch is None or remember:
159
branch.set_submit_branch(submit_branch)
160
if submit_branch is None:
161
submit_branch = branch.get_parent()
162
remembered_submit_branch = "parent"
163
if submit_branch is None:
164
raise errors.BzrCommandError('No submit branch known or'
166
if remembered_submit_branch is not None:
167
trace.note('Using saved %s location "%s" to determine what '
168
'changes to submit.', remembered_submit_branch,
172
submit_config = Branch.open(submit_branch).get_config()
173
mail_to = submit_config.get_user_option("child_submit_to")
175
stored_public_branch = branch.get_public_branch()
176
if public_branch is None:
177
public_branch = stored_public_branch
178
elif stored_public_branch is None or remember:
179
branch.set_public_branch(public_branch)
180
if no_bundle and public_branch is None:
181
raise errors.BzrCommandError('No public branch specified or'
183
base_revision_id = None
185
if revision is not None:
186
if len(revision) > 2:
187
raise errors.BzrCommandError('bzr send takes '
188
'at most two one revision identifiers')
189
revision_id = revision[-1].as_revision_id(branch)
190
if len(revision) == 2:
191
base_revision_id = revision[0].as_revision_id(branch)
192
if revision_id is None:
193
revision_id = branch.last_revision()
194
if revision_id == NULL_REVISION:
195
raise errors.BzrCommandError('No revisions to submit.')
197
# TODO: Query submit branch for its preferred format
198
format = format_registry.get()
199
directive = format(branch, revision_id, submit_branch,
200
public_branch, no_patch, no_bundle, message, base_revision_id)
202
directive.compose_merge_request(mail_client, mail_to, body,
208
outfile = open(output, 'wb')
210
outfile.writelines(directive.to_lines())
212
if outfile is not self.outf:
218
class cmd_bundle_revisions(cmd_send):
220
"""Create a merge-directive for submitting changes.
222
A merge directive provides many things needed for requesting merges:
224
* A machine-readable description of the merge to perform
226
* An optional patch that is a preview of the changes requested
228
* An optional bundle of revision data, so that the changes can be applied
229
directly from the merge directive, without retrieving data from a
232
If --no-bundle is specified, then public_branch is needed (and must be
233
up-to-date), so that the receiver can perform the merge using the
234
public_branch. The public_branch is always included if known, so that
235
people can check it later.
237
The submit branch defaults to the parent, but can be overridden. Both
238
submit branch and public branch will be remembered if supplied.
240
If a public_branch is known for the submit_branch, that public submit
241
branch is used in the merge instructions. This means that a local mirror
242
can be used as your actual submit branch, once you have set public_branch
245
Two formats are currently supported: "4" uses revision bundle format 4 and
246
merge directive format 2. It is significantly faster and smaller than
247
older formats. It is compatible with Bazaar 0.19 and later. It is the
248
default. "0.9" uses revision bundle format 0.9 and merge directive
249
format 1. It is compatible with Bazaar 0.12 - 0.18.
254
help='Do not include a bundle in the merge directive.'),
255
Option('no-patch', help='Do not include a preview patch in the merge'
258
help='Remember submit and public branch.'),
260
help='Branch to generate the submission from, '
261
'rather than the one containing the working directory.',
264
Option('output', short_name='o', help='Write directive to this file.',
267
RegistryOption('format',
268
help='Use the specified output format.',
269
registry=format_registry),
273
_see_also = ['send', 'merge']
277
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
278
no_patch=False, revision=None, remember=False, output=None,
279
format=None, **kwargs):
62
'Mail client "%s" does not support specifying body' %
63
mail_client.__class__.__name__)
64
if remember and submit_branch is None:
65
raise errors.BzrCommandError(
66
'--remember requires a branch to be specified.')
67
stored_submit_branch = branch.get_submit_branch()
68
remembered_submit_branch = None
69
if submit_branch is None:
70
submit_branch = stored_submit_branch
71
remembered_submit_branch = "submit"
73
if stored_submit_branch is None or remember:
74
branch.set_submit_branch(submit_branch)
75
if submit_branch is None:
76
submit_branch = branch.get_parent()
77
remembered_submit_branch = "parent"
78
if submit_branch is None:
79
raise errors.BzrCommandError('No submit branch known or'
81
if remembered_submit_branch is not None:
82
trace.note('Using saved %s location "%s" to determine what '
83
'changes to submit.', remembered_submit_branch,
87
submit_config = Branch.open(submit_branch).get_config()
88
mail_to = submit_config.get_user_option("child_submit_to")
90
stored_public_branch = branch.get_public_branch()
91
if public_branch is None:
92
public_branch = stored_public_branch
93
elif stored_public_branch is None or remember:
94
branch.set_public_branch(public_branch)
95
if no_bundle and public_branch is None:
96
raise errors.BzrCommandError('No public branch specified or'
98
base_revision_id = None
100
if revision is not None:
101
if len(revision) > 2:
102
raise errors.BzrCommandError('bzr send takes '
103
'at most two one revision identifiers')
104
revision_id = revision[-1].as_revision_id(branch)
105
if len(revision) == 2:
106
base_revision_id = revision[0].as_revision_id(branch)
107
if revision_id is None:
108
revision_id = branch.last_revision()
109
if revision_id == NULL_REVISION:
110
raise errors.BzrCommandError('No revisions to submit.')
112
# TODO: Query submit branch for its preferred format
113
format = format_registry.get()
114
directive = format(branch, revision_id, submit_branch,
115
public_branch, no_patch, no_bundle, message, base_revision_id)
280
116
if output is None:
282
return self._run(submit_branch, revision, public_branch, remember,
283
format, no_bundle, no_patch, output,
284
kwargs.get('from', '.'), None, None, None)
117
directive.compose_merge_request(mail_client, mail_to, body,
123
outfile = open(output, 'wb')
125
outfile.writelines(directive.to_lines())
127
if outfile is not to_file:
287
133
def _send_4(branch, revision_id, submit_branch, public_branch,