##// END OF EJS Templates
Don't validate email config if we're not sending email.
Bryan O'Sullivan -
r4565:1cf908c0 default
parent child Browse files
Show More
@@ -1,423 +1,425 b''
1 1 # Command for sending a collection of Mercurial changesets as a series
2 2 # of patch emails.
3 3 #
4 4 # The series is started off with a "[PATCH 0 of N]" introduction,
5 5 # which describes the series as a whole.
6 6 #
7 7 # Each patch email has a Subject line of "[PATCH M of N] ...", using
8 8 # the first line of the changeset description as the subject text.
9 9 # The message contains two or three body parts:
10 10 #
11 11 # The remainder of the changeset description.
12 12 #
13 13 # [Optional] If the diffstat program is installed, the result of
14 14 # running diffstat on the patch.
15 15 #
16 16 # The patch itself, as generated by "hg export".
17 17 #
18 18 # Each message refers to all of its predecessors using the In-Reply-To
19 19 # and References headers, so they will show up as a sequence in
20 20 # threaded mail and news readers, and in mail archives.
21 21 #
22 22 # For each changeset, you will be prompted with a diffstat summary and
23 23 # the changeset summary, so you can be sure you are sending the right
24 24 # changes.
25 25 #
26 26 # To enable this extension:
27 27 #
28 28 # [extensions]
29 29 # hgext.patchbomb =
30 30 #
31 31 # To configure other defaults, add a section like this to your hgrc
32 32 # file:
33 33 #
34 34 # [email]
35 35 # from = My Name <my@email>
36 36 # to = recipient1, recipient2, ...
37 37 # cc = cc1, cc2, ...
38 38 # bcc = bcc1, bcc2, ...
39 39 #
40 40 # Then you can use the "hg email" command to mail a series of changesets
41 41 # as a patchbomb.
42 42 #
43 43 # To avoid sending patches prematurely, it is a good idea to first run
44 44 # the "email" command with the "-n" option (test only). You will be
45 45 # prompted for an email recipient address, a subject an an introductory
46 46 # message describing the patches of your patchbomb. Then when all is
47 47 # done, your pager will be fired up once for each patchbomb message, so
48 48 # you can verify everything is alright.
49 49 #
50 50 # The "-m" (mbox) option is also very useful. Instead of previewing
51 51 # each patchbomb message in a pager or sending the messages directly,
52 52 # it will create a UNIX mailbox file with the patch emails. This
53 53 # mailbox file can be previewed with any mail user agent which supports
54 54 # UNIX mbox files, i.e. with mutt:
55 55 #
56 56 # % mutt -R -f mbox
57 57 #
58 58 # When you are previewing the patchbomb messages, you can use `formail'
59 59 # (a utility that is commonly installed as part of the procmail package),
60 60 # to send each message out:
61 61 #
62 62 # % formail -s sendmail -bm -t < mbox
63 63 #
64 64 # That should be all. Now your patchbomb is on its way out.
65 65
66 66 import os, errno, socket, tempfile
67 67 import email.MIMEMultipart, email.MIMEText, email.MIMEBase
68 68 import email.Utils, email.Encoders
69 69 from mercurial import cmdutil, commands, hg, mail, ui, patch, util
70 70 from mercurial.i18n import _
71 71 from mercurial.node import *
72 72
73 73 def patchbomb(ui, repo, *revs, **opts):
74 74 '''send changesets by email
75 75
76 76 By default, diffs are sent in the format generated by hg export,
77 77 one per message. The series starts with a "[PATCH 0 of N]"
78 78 introduction, which describes the series as a whole.
79 79
80 80 Each patch email has a Subject line of "[PATCH M of N] ...", using
81 81 the first line of the changeset description as the subject text.
82 82 The message contains two or three body parts. First, the rest of
83 83 the changeset description. Next, (optionally) if the diffstat
84 84 program is installed, the result of running diffstat on the patch.
85 85 Finally, the patch itself, as generated by "hg export".
86 86
87 87 With --outgoing, emails will be generated for patches not
88 88 found in the destination repository (or only those which are
89 89 ancestors of the specified revisions if any are provided)
90 90
91 91 With --bundle, changesets are selected as for --outgoing,
92 92 but a single email containing a binary Mercurial bundle as an
93 93 attachment will be sent.
94 94
95 95 Examples:
96 96
97 97 hg email -r 3000 # send patch 3000 only
98 98 hg email -r 3000 -r 3001 # send patches 3000 and 3001
99 99 hg email -r 3000:3005 # send patches 3000 through 3005
100 100 hg email 3000 # send patch 3000 (deprecated)
101 101
102 102 hg email -o # send all patches not in default
103 103 hg email -o DEST # send all patches not in DEST
104 104 hg email -o -r 3000 # send all ancestors of 3000 not in default
105 105 hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST
106 106
107 107 hg email -b # send bundle of all patches not in default
108 108 hg email -b DEST # send bundle of all patches not in DEST
109 109 hg email -b -r 3000 # bundle of all ancestors of 3000 not in default
110 110 hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST
111 111
112 112 Before using this command, you will need to enable email in your hgrc.
113 113 See the [email] section in hgrc(5) for details.
114 114 '''
115 115
116 116 def prompt(prompt, default = None, rest = ': ', empty_ok = False):
117 117 try:
118 118 # readline gives raw_input editing capabilities, but is not
119 119 # present on windows
120 120 import readline
121 121 except ImportError: pass
122 122
123 123 if default: prompt += ' [%s]' % default
124 124 prompt += rest
125 125 while True:
126 126 r = raw_input(prompt)
127 127 if r: return r
128 128 if default is not None: return default
129 129 if empty_ok: return r
130 130 ui.warn(_('Please enter a valid value.\n'))
131 131
132 132 def confirm(s):
133 133 if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'):
134 134 raise ValueError
135 135
136 136 def cdiffstat(summary, patchlines):
137 137 s = patch.diffstat(patchlines)
138 138 if s:
139 139 if summary:
140 140 ui.write(summary, '\n')
141 141 ui.write(s, '\n')
142 142 confirm(_('Does the diffstat above look okay'))
143 143 return s
144 144
145 145 def makepatch(patch, idx, total):
146 146 desc = []
147 147 node = None
148 148 body = ''
149 149 for line in patch:
150 150 if line.startswith('#'):
151 151 if line.startswith('# Node ID'): node = line.split()[-1]
152 152 continue
153 153 if (line.startswith('diff -r')
154 154 or line.startswith('diff --git')):
155 155 break
156 156 desc.append(line)
157 157 if not node: raise ValueError
158 158
159 159 #body = ('\n'.join(desc[1:]).strip() or
160 160 # 'Patch subject is complete summary.')
161 161 #body += '\n\n\n'
162 162
163 163 if opts['plain']:
164 164 while patch and patch[0].startswith('# '): patch.pop(0)
165 165 if patch: patch.pop(0)
166 166 while patch and not patch[0].strip(): patch.pop(0)
167 167 if opts['diffstat']:
168 168 body += cdiffstat('\n'.join(desc), patch) + '\n\n'
169 169 if opts['attach']:
170 170 msg = email.MIMEMultipart.MIMEMultipart()
171 171 if body: msg.attach(email.MIMEText.MIMEText(body, 'plain'))
172 172 p = email.MIMEText.MIMEText('\n'.join(patch), 'x-patch')
173 173 binnode = bin(node)
174 174 # if node is mq patch, it will have patch file name as tag
175 175 patchname = [t for t in repo.nodetags(binnode)
176 176 if t.endswith('.patch') or t.endswith('.diff')]
177 177 if patchname:
178 178 patchname = patchname[0]
179 179 elif total > 1:
180 180 patchname = cmdutil.make_filename(repo, '%b-%n.patch',
181 181 binnode, idx, total)
182 182 else:
183 183 patchname = cmdutil.make_filename(repo, '%b.patch', binnode)
184 184 p['Content-Disposition'] = 'inline; filename=' + patchname
185 185 msg.attach(p)
186 186 else:
187 187 body += '\n'.join(patch)
188 188 msg = email.MIMEText.MIMEText(body)
189 189
190 190 subj = desc[0].strip().rstrip('. ')
191 191 if total == 1:
192 192 subj = '[PATCH] ' + (opts['subject'] or subj)
193 193 else:
194 194 tlen = len(str(total))
195 195 subj = '[PATCH %0*d of %d] %s' % (tlen, idx, total, subj)
196 196 msg['Subject'] = subj
197 197 msg['X-Mercurial-Node'] = node
198 198 return msg
199 199
200 200 def outgoing(dest, revs):
201 201 '''Return the revisions present locally but not in dest'''
202 202 dest = ui.expandpath(dest or 'default-push', dest or 'default')
203 203 revs = [repo.lookup(rev) for rev in revs]
204 204 other = hg.repository(ui, dest)
205 205 ui.status(_('comparing with %s\n') % dest)
206 206 o = repo.findoutgoing(other)
207 207 if not o:
208 208 ui.status(_("no changes found\n"))
209 209 return []
210 210 o = repo.changelog.nodesbetween(o, revs or None)[0]
211 211 return [str(repo.changelog.rev(r)) for r in o]
212 212
213 213 def getbundle(dest):
214 214 tmpdir = tempfile.mkdtemp(prefix='hg-email-bundle-')
215 215 tmpfn = os.path.join(tmpdir, 'bundle')
216 216 try:
217 217 commands.bundle(ui, repo, tmpfn, dest, **opts)
218 218 return open(tmpfn).read()
219 219 finally:
220 220 try:
221 221 os.unlink(tmpfn)
222 222 except:
223 223 pass
224 224 os.rmdir(tmpdir)
225 225
226 if not opts['test']:
226 really_sending = not (opts['test'] or opts['mbox'])
227
228 if really_sending:
227 229 mail.validateconfig(ui)
228 230
229 231 if not (revs or opts.get('rev') or opts.get('outgoing')):
230 232 raise util.Abort(_('specify at least one changeset with -r or -o'))
231 233
232 234 cmdutil.setremoteconfig(ui, opts)
233 235 if opts.get('outgoing') and opts.get('bundle'):
234 236 raise util.Abort(_("--outgoing mode always on with --bundle; do not re-specify --outgoing"))
235 237
236 238 if opts.get('outgoing') or opts.get('bundle'):
237 239 if len(revs) > 1:
238 240 raise util.Abort(_("too many destinations"))
239 241 dest = revs and revs[0] or None
240 242 revs = []
241 243
242 244 if opts.get('rev'):
243 245 if revs:
244 246 raise util.Abort(_('use only one form to specify the revision'))
245 247 revs = opts.get('rev')
246 248
247 249 if opts.get('outgoing'):
248 250 revs = outgoing(dest, opts.get('rev'))
249 251 if opts.get('bundle'):
250 252 opts['revs'] = revs
251 253
252 254 # start
253 255 start_time = util.makedate()
254 256
255 257 def genmsgid(id):
256 258 return '<%s.%s@%s>' % (id[:20], int(start_time[0]), socket.getfqdn())
257 259
258 260 def getexportmsgs():
259 261 patches = []
260 262
261 263 class exportee:
262 264 def __init__(self, container):
263 265 self.lines = []
264 266 self.container = container
265 267 self.name = 'email'
266 268
267 269 def write(self, data):
268 270 self.lines.append(data)
269 271
270 272 def close(self):
271 273 self.container.append(''.join(self.lines).split('\n'))
272 274 self.lines = []
273 275
274 276 commands.export(ui, repo, *revs, **{'output': exportee(patches),
275 277 'switch_parent': False,
276 278 'text': None,
277 279 'git': opts.get('git')})
278 280
279 281 jumbo = []
280 282 msgs = []
281 283
282 284 ui.write(_('This patch series consists of %d patches.\n\n') % len(patches))
283 285
284 286 for p, i in zip(patches, xrange(len(patches))):
285 287 jumbo.extend(p)
286 288 msgs.append(makepatch(p, i + 1, len(patches)))
287 289
288 290 if len(patches) > 1:
289 291 tlen = len(str(len(patches)))
290 292
291 293 subj = '[PATCH %0*d of %d] %s' % (
292 294 tlen, 0,
293 295 len(patches),
294 296 opts['subject'] or
295 297 prompt('Subject:', rest = ' [PATCH %0*d of %d] ' % (tlen, 0,
296 298 len(patches))))
297 299
298 300 body = ''
299 301 if opts['diffstat']:
300 302 d = cdiffstat(_('Final summary:\n'), jumbo)
301 303 if d: body = '\n' + d
302 304
303 305 ui.write(_('\nWrite the introductory message for the patch series.\n\n'))
304 306 body = ui.edit(body, sender)
305 307
306 308 msg = email.MIMEText.MIMEText(body)
307 309 msg['Subject'] = subj
308 310
309 311 msgs.insert(0, msg)
310 312 return msgs
311 313
312 314 def getbundlemsgs(bundle):
313 315 subj = opts['subject'] or \
314 316 prompt('Subject:', default='A bundle for your repository')
315 317 ui.write(_('\nWrite the introductory message for the bundle.\n\n'))
316 318 body = ui.edit('', sender)
317 319
318 320 msg = email.MIMEMultipart.MIMEMultipart()
319 321 if body:
320 322 msg.attach(email.MIMEText.MIMEText(body, 'plain'))
321 323 datapart = email.MIMEBase.MIMEBase('application', 'x-mercurial-bundle')
322 324 datapart.set_payload(bundle)
323 325 datapart.add_header('Content-Disposition', 'attachment',
324 326 filename='bundle.hg')
325 327 email.Encoders.encode_base64(datapart)
326 328 msg.attach(datapart)
327 329 msg['Subject'] = subj
328 330 return [msg]
329 331
330 332 sender = (opts['from'] or ui.config('email', 'from') or
331 333 ui.config('patchbomb', 'from') or
332 334 prompt('From', ui.username()))
333 335
334 336 if opts.get('bundle'):
335 337 msgs = getbundlemsgs(getbundle(dest))
336 338 else:
337 339 msgs = getexportmsgs()
338 340
339 341 def getaddrs(opt, prpt, default = None):
340 342 addrs = opts[opt] or (ui.config('email', opt) or
341 343 ui.config('patchbomb', opt) or
342 344 prompt(prpt, default = default)).split(',')
343 345 return [a.strip() for a in addrs if a.strip()]
344 346
345 347 to = getaddrs('to', 'To')
346 348 cc = getaddrs('cc', 'Cc', '')
347 349
348 350 bcc = opts['bcc'] or (ui.config('email', 'bcc') or
349 351 ui.config('patchbomb', 'bcc') or '').split(',')
350 352 bcc = [a.strip() for a in bcc if a.strip()]
351 353
352 354 ui.write('\n')
353 355
354 if not opts['test'] and not opts['mbox']:
356 if really_sending:
355 357 mailer = mail.connect(ui)
356 358 parent = None
357 359
358 360 sender_addr = email.Utils.parseaddr(sender)[1]
359 361 for m in msgs:
360 362 try:
361 363 m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
362 364 except TypeError:
363 365 m['Message-Id'] = genmsgid('patchbomb')
364 366 if parent:
365 367 m['In-Reply-To'] = parent
366 368 else:
367 369 parent = m['Message-Id']
368 370 m['Date'] = util.datestr(date=start_time,
369 371 format="%a, %d %b %Y %H:%M:%S", timezone=True)
370 372
371 373 start_time = (start_time[0] + 1, start_time[1])
372 374 m['From'] = sender
373 375 m['To'] = ', '.join(to)
374 376 if cc: m['Cc'] = ', '.join(cc)
375 377 if bcc: m['Bcc'] = ', '.join(bcc)
376 378 if opts['test']:
377 379 ui.status('Displaying ', m['Subject'], ' ...\n')
378 380 fp = os.popen(os.getenv('PAGER', 'more'), 'w')
379 381 try:
380 382 fp.write(m.as_string(0))
381 383 fp.write('\n')
382 384 except IOError, inst:
383 385 if inst.errno != errno.EPIPE:
384 386 raise
385 387 fp.close()
386 388 elif opts['mbox']:
387 389 ui.status('Writing ', m['Subject'], ' ...\n')
388 390 fp = open(opts['mbox'], m.has_key('In-Reply-To') and 'ab+' or 'wb+')
389 391 date = util.datestr(date=start_time,
390 392 format='%a %b %d %H:%M:%S %Y', timezone=False)
391 393 fp.write('From %s %s\n' % (sender_addr, date))
392 394 fp.write(m.as_string(0))
393 395 fp.write('\n\n')
394 396 fp.close()
395 397 else:
396 398 ui.status('Sending ', m['Subject'], ' ...\n')
397 399 # Exim does not remove the Bcc field
398 400 del m['Bcc']
399 401 mailer.sendmail(sender, to + bcc + cc, m.as_string(0))
400 402
401 403 cmdtable = {
402 404 'email':
403 405 (patchbomb,
404 406 [('a', 'attach', None, 'send patches as inline attachments'),
405 407 ('', 'bcc', [], 'email addresses of blind copy recipients'),
406 408 ('c', 'cc', [], 'email addresses of copy recipients'),
407 409 ('d', 'diffstat', None, 'add diffstat output to messages'),
408 410 ('g', 'git', None, _('use git extended diff format')),
409 411 ('f', 'from', '', 'email address of sender'),
410 412 ('', 'plain', None, 'omit hg patch header'),
411 413 ('n', 'test', None, 'print messages that would be sent'),
412 414 ('m', 'mbox', '', 'write messages to mbox file instead of sending them'),
413 415 ('o', 'outgoing', None, _('send changes not found in the target repository')),
414 416 ('b', 'bundle', None, _('send changes not in target as a binary bundle')),
415 417 ('r', 'rev', [], _('a revision to send')),
416 418 ('s', 'subject', '', 'subject of first message (intro or single patch)'),
417 419 ('t', 'to', [], 'email addresses of recipients'),
418 420 ('', 'force', None, _('run even when remote repository is unrelated (with -b)')),
419 421 ('', 'base', [],
420 422 _('a base changeset to specify instead of a destination (with -b)'))]
421 423 + commands.remoteopts,
422 424 "hg email [OPTION]... [DEST]...")
423 425 }
@@ -1,17 +1,19 b''
1 1 #!/bin/sh
2 2
3 3 echo "[extensions]" >> $HGRCPATH
4 4 echo "patchbomb=" >> $HGRCPATH
5 5
6 6 hg init
7 7 echo a > a
8 8 hg commit -Ama -d '1 0'
9 9
10 10 hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar tip | \
11 11 sed -e 's/\(Message-Id:.*@\).*/\1/'
12 12
13 13 echo b > b
14 14 hg commit -Amb -d '2 0'
15 15
16 16 hg email --date '1970-1-1 0:2' -n -f quux -t foo -c bar -s test 0:tip | \
17 17 sed -e 's/\(Message-Id:.*@\|In-Reply-To:.*@\).*/\1/'
18
19 hg email -m test.mbox -f quux -t foo -c bar -s test 0:tip
@@ -1,134 +1,143 b''
1 1 adding a
2 2 hg email: option --date not recognized
3 3 hg email [OPTION]... [DEST]...
4 4
5 5 send changesets by email
6 6
7 7 By default, diffs are sent in the format generated by hg export,
8 8 one per message. The series starts with a "[PATCH 0 of N]"
9 9 introduction, which describes the series as a whole.
10 10
11 11 Each patch email has a Subject line of "[PATCH M of N] ...", using
12 12 the first line of the changeset description as the subject text.
13 13 The message contains two or three body parts. First, the rest of
14 14 the changeset description. Next, (optionally) if the diffstat
15 15 program is installed, the result of running diffstat on the patch.
16 16 Finally, the patch itself, as generated by "hg export".
17 17
18 18 With --outgoing, emails will be generated for patches not
19 19 found in the destination repository (or only those which are
20 20 ancestors of the specified revisions if any are provided)
21 21
22 22 With --bundle, changesets are selected as for --outgoing,
23 23 but a single email containing a binary Mercurial bundle as an
24 24 attachment will be sent.
25 25
26 26 Examples:
27 27
28 28 hg email -r 3000 # send patch 3000 only
29 29 hg email -r 3000 -r 3001 # send patches 3000 and 3001
30 30 hg email -r 3000:3005 # send patches 3000 through 3005
31 31 hg email 3000 # send patch 3000 (deprecated)
32 32
33 33 hg email -o # send all patches not in default
34 34 hg email -o DEST # send all patches not in DEST
35 35 hg email -o -r 3000 # send all ancestors of 3000 not in default
36 36 hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST
37 37
38 38 hg email -b # send bundle of all patches not in default
39 39 hg email -b DEST # send bundle of all patches not in DEST
40 40 hg email -b -r 3000 # bundle of all ancestors of 3000 not in default
41 41 hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST
42 42
43 43 Before using this command, you will need to enable email in your hgrc.
44 44 See the [email] section in hgrc(5) for details.
45 45
46 46 options:
47 47
48 48 -a --attach send patches as inline attachments
49 49 --bcc email addresses of blind copy recipients
50 50 -c --cc email addresses of copy recipients
51 51 -d --diffstat add diffstat output to messages
52 52 -g --git use git extended diff format
53 53 -f --from email address of sender
54 54 --plain omit hg patch header
55 55 -n --test print messages that would be sent
56 56 -m --mbox write messages to mbox file instead of sending them
57 57 -o --outgoing send changes not found in the target repository
58 58 -b --bundle send changes not in target as a binary bundle
59 59 -r --rev a revision to send
60 60 -s --subject subject of first message (intro or single patch)
61 61 -t --to email addresses of recipients
62 62 --force run even when remote repository is unrelated (with -b)
63 63 --base a base changeset to specify instead of a destination (with -b)
64 64 -e --ssh specify ssh command to use
65 65 --remotecmd specify hg command to run on the remote side
66 66
67 67 use "hg -v help email" to show global options
68 68 adding b
69 69 hg email: option --date not recognized
70 70 hg email [OPTION]... [DEST]...
71 71
72 72 send changesets by email
73 73
74 74 By default, diffs are sent in the format generated by hg export,
75 75 one per message. The series starts with a "[PATCH 0 of N]"
76 76 introduction, which describes the series as a whole.
77 77
78 78 Each patch email has a Subject line of "[PATCH M of N] ...", using
79 79 the first line of the changeset description as the subject text.
80 80 The message contains two or three body parts. First, the rest of
81 81 the changeset description. Next, (optionally) if the diffstat
82 82 program is installed, the result of running diffstat on the patch.
83 83 Finally, the patch itself, as generated by "hg export".
84 84
85 85 With --outgoing, emails will be generated for patches not
86 86 found in the destination repository (or only those which are
87 87 ancestors of the specified revisions if any are provided)
88 88
89 89 With --bundle, changesets are selected as for --outgoing,
90 90 but a single email containing a binary Mercurial bundle as an
91 91 attachment will be sent.
92 92
93 93 Examples:
94 94
95 95 hg email -r 3000 # send patch 3000 only
96 96 hg email -r 3000 -r 3001 # send patches 3000 and 3001
97 97 hg email -r 3000:3005 # send patches 3000 through 3005
98 98 hg email 3000 # send patch 3000 (deprecated)
99 99
100 100 hg email -o # send all patches not in default
101 101 hg email -o DEST # send all patches not in DEST
102 102 hg email -o -r 3000 # send all ancestors of 3000 not in default
103 103 hg email -o -r 3000 DEST # send all ancestors of 3000 not in DEST
104 104
105 105 hg email -b # send bundle of all patches not in default
106 106 hg email -b DEST # send bundle of all patches not in DEST
107 107 hg email -b -r 3000 # bundle of all ancestors of 3000 not in default
108 108 hg email -b -r 3000 DEST # bundle of all ancestors of 3000 not in DEST
109 109
110 110 Before using this command, you will need to enable email in your hgrc.
111 111 See the [email] section in hgrc(5) for details.
112 112
113 113 options:
114 114
115 115 -a --attach send patches as inline attachments
116 116 --bcc email addresses of blind copy recipients
117 117 -c --cc email addresses of copy recipients
118 118 -d --diffstat add diffstat output to messages
119 119 -g --git use git extended diff format
120 120 -f --from email address of sender
121 121 --plain omit hg patch header
122 122 -n --test print messages that would be sent
123 123 -m --mbox write messages to mbox file instead of sending them
124 124 -o --outgoing send changes not found in the target repository
125 125 -b --bundle send changes not in target as a binary bundle
126 126 -r --rev a revision to send
127 127 -s --subject subject of first message (intro or single patch)
128 128 -t --to email addresses of recipients
129 129 --force run even when remote repository is unrelated (with -b)
130 130 --base a base changeset to specify instead of a destination (with -b)
131 131 -e --ssh specify ssh command to use
132 132 --remotecmd specify hg command to run on the remote side
133 133
134 134 use "hg -v help email" to show global options
135 This patch series consists of 2 patches.
136
137
138 Write the introductory message for the patch series.
139
140
141 Writing [PATCH 0 of 2] test ...
142 Writing [PATCH 1 of 2] a ...
143 Writing [PATCH 2 of 2] b ...
General Comments 0
You need to be logged in to leave comments. Login now