Mercurial > hg > mercurial-crew-with-dirclash
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'), |