Mercurial > hg
comparison hgext/patchbomb.py @ 7353:982b55ec80be
patchbomb: make `hg email` reusable for other patch sources
Adds two internal options, patches and patchnames, which allow other extensions
to email a given set of patches. The pbranch extension needs this to send its
patches which are diffs between topic branches.
author | Peter Arrenbrecht <peter.arrenbrecht@gmail.com> |
---|---|
date | Wed, 12 Nov 2008 14:07:47 +0100 |
parents | 6c336e7dc145 |
children | cad454f295b0 |
comparison
equal
deleted
inserted
replaced
7352:6c336e7dc145 | 7353:982b55ec80be |
---|---|
157 elif s is None: | 157 elif s is None: |
158 ui.warn(_('No diffstat information available.\n')) | 158 ui.warn(_('No diffstat information available.\n')) |
159 s = '' | 159 s = '' |
160 return s | 160 return s |
161 | 161 |
162 def makepatch(patch, idx, total): | 162 def makepatch(patch, idx, total, patchname=None): |
163 desc = [] | 163 desc = [] |
164 node = None | 164 node = None |
165 body = '' | 165 body = '' |
166 for line in patch: | 166 for line in patch: |
167 if line.startswith('#'): | 167 if line.startswith('#'): |
169 node = line.split()[-1] | 169 node = line.split()[-1] |
170 continue | 170 continue |
171 if line.startswith('diff -r') or line.startswith('diff --git'): | 171 if line.startswith('diff -r') or line.startswith('diff --git'): |
172 break | 172 break |
173 desc.append(line) | 173 desc.append(line) |
174 if not node: | 174 if not patchname and not node: |
175 raise ValueError | 175 raise ValueError |
176 | 176 |
177 if opts.get('attach'): | 177 if opts.get('attach'): |
178 body = ('\n'.join(desc[1:]).strip() or | 178 body = ('\n'.join(desc[1:]).strip() or |
179 'Patch subject is complete summary.') | 179 'Patch subject is complete summary.') |
195 opts.get('test'))) | 195 opts.get('test'))) |
196 p = mail.mimetextpatch('\n'.join(patch), 'x-patch', | 196 p = mail.mimetextpatch('\n'.join(patch), 'x-patch', |
197 opts.get('test')) | 197 opts.get('test')) |
198 binnode = bin(node) | 198 binnode = bin(node) |
199 # if node is mq patch, it will have patch file name as tag | 199 # if node is mq patch, it will have patch file name as tag |
200 patchname = [t for t in repo.nodetags(binnode) | 200 if not patchname: |
201 if t.endswith('.patch') or t.endswith('.diff')] | 201 patchtags = [t for t in repo.nodetags(binnode) |
202 if patchname: | 202 if t.endswith('.patch') or t.endswith('.diff')] |
203 patchname = patchname[0] | 203 if patchtags: |
204 elif total > 1: | 204 patchname = patchtags[0] |
205 patchname = cmdutil.make_filename(repo, '%b-%n.patch', | 205 elif total > 1: |
206 binnode, idx, total) | 206 patchname = cmdutil.make_filename(repo, '%b-%n.patch', |
207 else: | 207 binnode, idx, total) |
208 patchname = cmdutil.make_filename(repo, '%b.patch', binnode) | 208 else: |
209 patchname = cmdutil.make_filename(repo, '%b.patch', binnode) | |
209 disposition = 'inline' | 210 disposition = 'inline' |
210 if opts.get('attach'): | 211 if opts.get('attach'): |
211 disposition = 'attachment' | 212 disposition = 'attachment' |
212 p['Content-Disposition'] = disposition + '; filename=' + patchname | 213 p['Content-Disposition'] = disposition + '; filename=' + patchname |
213 msg.attach(p) | 214 msg.attach(p) |
254 if not (opts.get('test') or opts.get('mbox')): | 255 if not (opts.get('test') or opts.get('mbox')): |
255 # really sending | 256 # really sending |
256 mail.validateconfig(ui) | 257 mail.validateconfig(ui) |
257 | 258 |
258 if not (revs or opts.get('rev') | 259 if not (revs or opts.get('rev') |
259 or opts.get('outgoing') or opts.get('bundle')): | 260 or opts.get('outgoing') or opts.get('bundle') |
261 or opts.get('patches')): | |
260 raise util.Abort(_('specify at least one changeset with -r or -o')) | 262 raise util.Abort(_('specify at least one changeset with -r or -o')) |
261 | 263 |
262 cmdutil.setremoteconfig(ui, opts) | 264 cmdutil.setremoteconfig(ui, opts) |
263 if opts.get('outgoing') and opts.get('bundle'): | 265 if opts.get('outgoing') and opts.get('bundle'): |
264 raise util.Abort(_("--outgoing mode always on with --bundle;" | 266 raise util.Abort(_("--outgoing mode always on with --bundle;" |
296 ui.write(_('\nWrite the introductory message for the ' | 298 ui.write(_('\nWrite the introductory message for the ' |
297 'patch series.\n\n')) | 299 'patch series.\n\n')) |
298 body = ui.edit(body, sender) | 300 body = ui.edit(body, sender) |
299 return body | 301 return body |
300 | 302 |
301 def getexportmsgs(): | 303 def getpatchmsgs(patches, patchnames=None): |
302 patches = [] | |
303 commands.export(ui, repo, *revs, **{'output': exportee(patches), | |
304 'switch_parent': False, | |
305 'text': None, | |
306 'git': opts.get('git')}) | |
307 | |
308 jumbo = [] | 304 jumbo = [] |
309 msgs = [] | 305 msgs = [] |
310 | 306 |
311 ui.write(_('This patch series consists of %d patches.\n\n') | 307 ui.write(_('This patch series consists of %d patches.\n\n') |
312 % len(patches)) | 308 % len(patches)) |
313 | 309 |
310 name = None | |
314 for p, i in zip(patches, xrange(len(patches))): | 311 for p, i in zip(patches, xrange(len(patches))): |
315 jumbo.extend(p) | 312 jumbo.extend(p) |
316 msgs.append(makepatch(p, i + 1, len(patches))) | 313 if patchnames: |
314 name = patchnames[i] | |
315 msgs.append(makepatch(p, i + 1, len(patches), name)) | |
317 | 316 |
318 if len(patches) > 1: | 317 if len(patches) > 1: |
319 tlen = len(str(len(patches))) | 318 tlen = len(str(len(patches))) |
320 | 319 |
321 subj = '[PATCH %0*d of %d] %s' % ( | 320 subj = '[PATCH %0*d of %d] %s' % ( |
357 | 356 |
358 sender = (opts.get('from') or ui.config('email', 'from') or | 357 sender = (opts.get('from') or ui.config('email', 'from') or |
359 ui.config('patchbomb', 'from') or | 358 ui.config('patchbomb', 'from') or |
360 prompt('From', ui.username())) | 359 prompt('From', ui.username())) |
361 | 360 |
362 if opts.get('bundle'): | 361 patches = opts.get('patches') |
362 if patches: | |
363 msgs = getpatchmsgs(patches, opts.get('patchnames')) | |
364 elif opts.get('bundle'): | |
363 msgs = getbundlemsgs(getbundle(dest)) | 365 msgs = getbundlemsgs(getbundle(dest)) |
364 else: | 366 else: |
365 msgs = getexportmsgs() | 367 patches = [] |
368 commands.export(ui, repo, *revs, **{'output': exportee(patches), | |
369 'switch_parent': False, | |
370 'text': None, | |
371 'git': opts.get('git')}) | |
372 msgs = getpatchmsgs(patches) | |
366 | 373 |
367 def getaddrs(opt, prpt, default = None): | 374 def getaddrs(opt, prpt, default = None): |
368 addrs = opts.get(opt) or (ui.config('email', opt) or | 375 addrs = opts.get(opt) or (ui.config('email', opt) or |
369 ui.config('patchbomb', opt) or | 376 ui.config('patchbomb', opt) or |
370 prompt(prpt, default = default)).split(',') | 377 prompt(prpt, default = default)).split(',') |