304 else: |
304 else: |
305 patchname = cmdutil.makefilename(repo[node], b'%b.patch') |
305 patchname = cmdutil.makefilename(repo[node], b'%b.patch') |
306 disposition = r'inline' |
306 disposition = r'inline' |
307 if opts.get(b'attach'): |
307 if opts.get(b'attach'): |
308 disposition = r'attachment' |
308 disposition = r'attachment' |
309 p[r'Content-Disposition'] = ( |
309 p['Content-Disposition'] = ( |
310 disposition + r'; filename=' + encoding.strfromlocal(patchname) |
310 disposition + '; filename=' + encoding.strfromlocal(patchname) |
311 ) |
311 ) |
312 msg.attach(p) |
312 msg.attach(p) |
313 else: |
313 else: |
314 msg = mail.mimetextpatch(body, display=opts.get(b'test')) |
314 msg = mail.mimetextpatch(body, display=opts.get(b'test')) |
315 |
315 |
356 ui = repo.ui |
356 ui = repo.ui |
357 tmpdir = pycompat.mkdtemp(prefix=b'hg-email-bundle-') |
357 tmpdir = pycompat.mkdtemp(prefix=b'hg-email-bundle-') |
358 tmpfn = os.path.join(tmpdir, b'bundle') |
358 tmpfn = os.path.join(tmpdir, b'bundle') |
359 btype = ui.config(b'patchbomb', b'bundletype') |
359 btype = ui.config(b'patchbomb', b'bundletype') |
360 if btype: |
360 if btype: |
361 opts[r'type'] = btype |
361 opts['type'] = btype |
362 try: |
362 try: |
363 commands.bundle(ui, repo, tmpfn, dest, **opts) |
363 commands.bundle(ui, repo, tmpfn, dest, **opts) |
364 return util.readfile(tmpfn) |
364 return util.readfile(tmpfn) |
365 finally: |
365 finally: |
366 try: |
366 try: |
401 This function returns a list of "email" tuples (subject, content, None). |
401 This function returns a list of "email" tuples (subject, content, None). |
402 The list is always one message long in that case. |
402 The list is always one message long in that case. |
403 """ |
403 """ |
404 ui = repo.ui |
404 ui = repo.ui |
405 _charsets = mail._charsets(ui) |
405 _charsets = mail._charsets(ui) |
406 subj = opts.get(r'subject') or prompt( |
406 subj = opts.get('subject') or prompt( |
407 ui, b'Subject:', b'A bundle for your repository' |
407 ui, b'Subject:', b'A bundle for your repository' |
408 ) |
408 ) |
409 |
409 |
410 body = _getdescription(repo, b'', sender, **opts) |
410 body = _getdescription(repo, b'', sender, **opts) |
411 msg = emimemultipart.MIMEMultipart() |
411 msg = emimemultipart.MIMEMultipart() |
412 if body: |
412 if body: |
413 msg.attach(mail.mimeencode(ui, body, _charsets, opts.get(r'test'))) |
413 msg.attach(mail.mimeencode(ui, body, _charsets, opts.get('test'))) |
414 datapart = emimebase.MIMEBase(r'application', r'x-mercurial-bundle') |
414 datapart = emimebase.MIMEBase('application', 'x-mercurial-bundle') |
415 datapart.set_payload(bundle) |
415 datapart.set_payload(bundle) |
416 bundlename = b'%s.hg' % opts.get(r'bundlename', b'bundle') |
416 bundlename = b'%s.hg' % opts.get('bundlename', b'bundle') |
417 datapart.add_header( |
417 datapart.add_header( |
418 r'Content-Disposition', |
418 'Content-Disposition', |
419 r'attachment', |
419 'attachment', |
420 filename=encoding.strfromlocal(bundlename), |
420 filename=encoding.strfromlocal(bundlename), |
421 ) |
421 ) |
422 emailencoders.encode_base64(datapart) |
422 emailencoders.encode_base64(datapart) |
423 msg.attach(datapart) |
423 msg.attach(datapart) |
424 msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get(r'test')) |
424 msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test')) |
425 return [(msg, subj, None)] |
425 return [(msg, subj, None)] |
426 |
426 |
427 |
427 |
428 def _makeintro(repo, sender, revs, patches, **opts): |
428 def _makeintro(repo, sender, revs, patches, **opts): |
429 """make an introduction email, asking the user for content if needed |
429 """make an introduction email, asking the user for content if needed |
432 ui = repo.ui |
432 ui = repo.ui |
433 _charsets = mail._charsets(ui) |
433 _charsets = mail._charsets(ui) |
434 |
434 |
435 # use the last revision which is likely to be a bookmarked head |
435 # use the last revision which is likely to be a bookmarked head |
436 prefix = _formatprefix( |
436 prefix = _formatprefix( |
437 ui, repo, revs.last(), opts.get(r'flag'), 0, len(patches), numbered=True |
437 ui, repo, revs.last(), opts.get('flag'), 0, len(patches), numbered=True |
438 ) |
438 ) |
439 subj = opts.get(r'subject') or prompt( |
439 subj = opts.get('subject') or prompt( |
440 ui, b'(optional) Subject: ', rest=prefix, default=b'' |
440 ui, b'(optional) Subject: ', rest=prefix, default=b'' |
441 ) |
441 ) |
442 if not subj: |
442 if not subj: |
443 return None # skip intro if the user doesn't bother |
443 return None # skip intro if the user doesn't bother |
444 |
444 |
445 subj = prefix + b' ' + subj |
445 subj = prefix + b' ' + subj |
446 |
446 |
447 body = b'' |
447 body = b'' |
448 if opts.get(r'diffstat'): |
448 if opts.get('diffstat'): |
449 # generate a cumulative diffstat of the whole patch series |
449 # generate a cumulative diffstat of the whole patch series |
450 diffstat = patch.diffstat(sum(patches, [])) |
450 diffstat = patch.diffstat(sum(patches, [])) |
451 body = b'\n' + diffstat |
451 body = b'\n' + diffstat |
452 else: |
452 else: |
453 diffstat = None |
453 diffstat = None |
454 |
454 |
455 body = _getdescription(repo, body, sender, **opts) |
455 body = _getdescription(repo, body, sender, **opts) |
456 msg = mail.mimeencode(ui, body, _charsets, opts.get(r'test')) |
456 msg = mail.mimeencode(ui, body, _charsets, opts.get('test')) |
457 msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get(r'test')) |
457 msg[b'Subject'] = mail.headencode(ui, subj, _charsets, opts.get('test')) |
458 return (msg, subj, diffstat) |
458 return (msg, subj, diffstat) |
459 |
459 |
460 |
460 |
461 def _getpatchmsgs(repo, sender, revs, patchnames=None, **opts): |
461 def _getpatchmsgs(repo, sender, revs, patchnames=None, **opts): |
462 """return a list of emails from a list of patches |
462 """return a list of emails from a list of patches |
845 |
845 |
846 if bundle: |
846 if bundle: |
847 stropts = pycompat.strkwargs(opts) |
847 stropts = pycompat.strkwargs(opts) |
848 bundledata = _getbundle(repo, dest, **stropts) |
848 bundledata = _getbundle(repo, dest, **stropts) |
849 bundleopts = stropts.copy() |
849 bundleopts = stropts.copy() |
850 bundleopts.pop(r'bundle', None) # already processed |
850 bundleopts.pop('bundle', None) # already processed |
851 msgs = _getbundlemsgs(repo, sender, bundledata, **bundleopts) |
851 msgs = _getbundlemsgs(repo, sender, bundledata, **bundleopts) |
852 else: |
852 else: |
853 msgs = _getpatchmsgs(repo, sender, revs, **pycompat.strkwargs(opts)) |
853 msgs = _getpatchmsgs(repo, sender, revs, **pycompat.strkwargs(opts)) |
854 |
854 |
855 showaddrs = [] |
855 showaddrs = [] |