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')) |