comparison hgext/patchbomb.py @ 3098:fe9b13e35e46

Merge with crew
author Matt Mackall <mpm@selenic.com>
date Fri, 15 Sep 2006 15:22:45 -0500
parents f422c8265ae5
children 1e2941fda520
comparison
equal deleted inserted replaced
3097:1b738357bba9 3098:fe9b13e35e46
63 # 63 #
64 # That should be all. Now your patchbomb is on its way out. 64 # That should be all. Now your patchbomb is on its way out.
65 65
66 from mercurial.demandload import * 66 from mercurial.demandload import *
67 demandload(globals(), '''email.MIMEMultipart email.MIMEText email.Utils 67 demandload(globals(), '''email.MIMEMultipart email.MIMEText email.Utils
68 mercurial:commands,hg,mail,ui 68 mercurial:commands,hg,mail,ui,patch
69 os errno popen2 socket sys tempfile time''') 69 os errno popen2 socket sys tempfile time''')
70 from mercurial.i18n import gettext as _ 70 from mercurial.i18n import gettext as _
71 from mercurial.node import * 71 from mercurial.node import *
72 72
73 try: 73 try:
74 # readline gives raw_input editing capabilities, but is not 74 # readline gives raw_input editing capabilities, but is not
75 # present on windows 75 # present on windows
76 import readline 76 import readline
77 except ImportError: pass 77 except ImportError: pass
78
79 def diffstat(patch):
80 fd, name = tempfile.mkstemp(prefix="hg-patchbomb-", suffix=".txt")
81 try:
82 p = popen2.Popen3('diffstat -p1 -w79 2>/dev/null > ' + name)
83 try:
84 for line in patch: print >> p.tochild, line
85 p.tochild.close()
86 if p.wait(): return
87 fp = os.fdopen(fd, 'r')
88 stat = []
89 for line in fp: stat.append(line.lstrip())
90 last = stat.pop()
91 stat.insert(0, last)
92 stat = ''.join(stat)
93 if stat.startswith('0 files'): raise ValueError
94 return stat
95 except: raise
96 finally:
97 try: os.unlink(name)
98 except: pass
99 78
100 def patchbomb(ui, repo, *revs, **opts): 79 def patchbomb(ui, repo, *revs, **opts):
101 '''send changesets as a series of patch emails 80 '''send changesets as a series of patch emails
102 81
103 The series starts with a "[PATCH 0 of N]" introduction, which 82 The series starts with a "[PATCH 0 of N]" introduction, which
121 100
122 def confirm(s): 101 def confirm(s):
123 if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'): 102 if not prompt(s, default = 'y', rest = '? ').lower().startswith('y'):
124 raise ValueError 103 raise ValueError
125 104
126 def cdiffstat(summary, patch): 105 def cdiffstat(summary, patchlines):
127 s = diffstat(patch) 106 s = patch.diffstat(patchlines)
128 if s: 107 if s:
129 if summary: 108 if summary:
130 ui.write(summary, '\n') 109 ui.write(summary, '\n')
131 ui.write(s, '\n') 110 ui.write(s, '\n')
132 confirm(_('Does the diffstat above look okay')) 111 confirm(_('Does the diffstat above look okay'))
138 body = '' 117 body = ''
139 for line in patch: 118 for line in patch:
140 if line.startswith('#'): 119 if line.startswith('#'):
141 if line.startswith('# Node ID'): node = line.split()[-1] 120 if line.startswith('# Node ID'): node = line.split()[-1]
142 continue 121 continue
143 if line.startswith('diff -r'): break 122 if (line.startswith('diff -r')
123 or line.startswith('diff --git')):
124 break
144 desc.append(line) 125 desc.append(line)
145 if not node: raise ValueError 126 if not node: raise ValueError
146 127
147 #body = ('\n'.join(desc[1:]).strip() or 128 #body = ('\n'.join(desc[1:]).strip() or
148 # 'Patch subject is complete summary.') 129 # 'Patch subject is complete summary.')
203 self.container.append(''.join(self.lines).split('\n')) 184 self.container.append(''.join(self.lines).split('\n'))
204 self.lines = [] 185 self.lines = []
205 186
206 commands.export(ui, repo, *revs, **{'output': exportee(patches), 187 commands.export(ui, repo, *revs, **{'output': exportee(patches),
207 'switch_parent': False, 188 'switch_parent': False,
208 'text': None}) 189 'text': None,
190 'git': opts.get('git')})
209 191
210 jumbo = [] 192 jumbo = []
211 msgs = [] 193 msgs = []
212 194
213 ui.write(_('This patch series consists of %d patches.\n\n') % len(patches)) 195 ui.write(_('This patch series consists of %d patches.\n\n') % len(patches))
320 (patchbomb, 302 (patchbomb,
321 [('a', 'attach', None, 'send patches as inline attachments'), 303 [('a', 'attach', None, 'send patches as inline attachments'),
322 ('', 'bcc', [], 'email addresses of blind copy recipients'), 304 ('', 'bcc', [], 'email addresses of blind copy recipients'),
323 ('c', 'cc', [], 'email addresses of copy recipients'), 305 ('c', 'cc', [], 'email addresses of copy recipients'),
324 ('d', 'diffstat', None, 'add diffstat output to messages'), 306 ('d', 'diffstat', None, 'add diffstat output to messages'),
307 ('g', 'git', None, _('use git extended diff format')),
325 ('f', 'from', '', 'email address of sender'), 308 ('f', 'from', '', 'email address of sender'),
326 ('', 'plain', None, 'omit hg patch header'), 309 ('', 'plain', None, 'omit hg patch header'),
327 ('n', 'test', None, 'print messages that would be sent'), 310 ('n', 'test', None, 'print messages that would be sent'),
328 ('m', 'mbox', '', 'write messages to mbox file instead of sending them'), 311 ('m', 'mbox', '', 'write messages to mbox file instead of sending them'),
329 ('s', 'subject', '', 'subject of introductory message'), 312 ('s', 'subject', '', 'subject of introductory message'),