--- a/contrib/check-code.py Tue Mar 16 11:37:14 2010 -0300
+++ b/contrib/check-code.py Fri Mar 19 16:04:49 2010 -0500
@@ -10,9 +10,15 @@
import sys, re, glob
def repquote(m):
- t = re.sub(r"\w", "x", m.group(2))
+ t = re.sub(r"\w", "x", m.group('text'))
t = re.sub(r"[^\sx]", "o", t)
- return m.group(1) + t + m.group(1)
+ return m.group('quote') + t + m.group('quote')
+
+def reppython(m):
+ comment = m.group('comment')
+ if comment:
+ return "#" * len(comment)
+ return repquote(m)
def repcomment(m):
return m.group(1) + "#" * len(m.group(2))
@@ -96,11 +102,10 @@
]
pyfilters = [
- (r"""(''')(([^']|\\'|'{1,2}(?!'))*)'''""", repquote),
- (r'''(""")(([^"]|\\"|"{1,2}(?!"))*)"""''', repquote),
- (r'''(?<!")(")(([^"\n]|\\")+)"(?!")''', repquote),
- (r"""(?<!')(')(([^'\n]|\\')+)'(?!')""", repquote),
- (r"( *)(#([^\n]*\S)?)", repcomment),
+ (r"""(?msx)(?P<comment>\#.*?$)|
+ ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
+ (?P<text>(([^\\]|\\.)*?))
+ (?P=quote))""", reppython),
]
cpats = [
@@ -123,7 +128,7 @@
cfilters = [
(r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment),
- (r'''(?<!")(")(([^"]|\\")+"(?!"))''', repquote),
+ (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote),
(r'''(#\s*include\s+<)([^>]+)>''', repinclude),
(r'(\()([^)]+\))', repcallspaces),
]
@@ -134,12 +139,42 @@
('c', r'.*\.c$', cfilters, cpats),
]
-if len(sys.argv) == 1:
- check = glob.glob("*")
-else:
- check = sys.argv[1:]
+class norepeatlogger(object):
+ def __init__(self):
+ self._lastseen = None
+
+ def log(self, fname, lineno, line, msg):
+ """print error related a to given line of a given file.
+
+ The faulty line will also be printed but only once in the case
+ of multiple errors.
-for f in check:
+ :fname: filename
+ :lineno: line number
+ :line: actual content of the line
+ :msg: error message
+ """
+ msgid = fname, lineno, line
+ if msgid != self._lastseen:
+ print "%s:%d:" % (fname, lineno)
+ print " > %s" % line
+ self._lastseen = msgid
+ print " " + msg
+
+_defaultlogger = norepeatlogger()
+
+def checkfile(f, logfunc=_defaultlogger.log, maxerr=None):
+ """checks style and portability of a given file
+
+ :f: filepath
+ :logfunc: function used to report error
+ logfunc(filename, linenumber, linecontent, errormessage)
+ :maxerr: number of error to display before arborting.
+ Set to None (default) to report all errors
+
+ return True if no error is found, False otherwise.
+ """
+ result = True
for name, match, filters, pats in checks:
fc = 0
if not re.match(match, f):
@@ -154,16 +189,23 @@
for n, l in z:
if "check-code" + "-ignore" in l[0]:
continue
- lc = 0
for p, msg in pats:
if re.search(p, l[1]):
- if not lc:
- print "%s:%d:" % (f, n + 1)
- print " > %s" % l[0]
- print " %s" % msg
- lc += 1
+ logfunc(f, n + 1, l[0], msg)
fc += 1
- if fc == 15:
+ result = False
+ if maxerr is not None and fc >= maxerr:
print " (too many errors, giving up)"
break
break
+ return result
+
+
+if __name__ == "__main__":
+ if len(sys.argv) == 1:
+ check = glob.glob("*")
+ else:
+ check = sys.argv[1:]
+
+ for f in check:
+ checkfile(f, maxerr=15)
--- a/contrib/shrink-revlog.py Tue Mar 16 11:37:14 2010 -0300
+++ b/contrib/shrink-revlog.py Fri Mar 19 16:04:49 2010 -0500
@@ -64,7 +64,7 @@
for p in parents[rev]:
heads.discard(p)
finally:
- ui.progress(_('reading'), None, total=len(rl))
+ ui.progress(_('reading'), None)
heads = list(heads)
heads.sort(reverse=True)
@@ -90,7 +90,7 @@
if p2 != node.nullrev:
children[p2].append(rev)
finally:
- ui.progress(_('reading'), None, total=len(rl))
+ ui.progress(_('reading'), None)
root = list(roots)
roots.sort()
@@ -120,7 +120,7 @@
chunkiter = changegroup.chunkiter(group)
r2.addgroup(chunkiter, unlookup, tr)
finally:
- ui.progress(_('writing'), None, len(order))
+ ui.progress(_('writing'), None)
def report(ui, r1, r2):
def getsize(r):
--- a/contrib/wix/mercurial.wxs Tue Mar 16 11:37:14 2010 -0300
+++ b/contrib/wix/mercurial.wxs Fri Mar 19 16:04:49 2010 -0500
@@ -9,7 +9,7 @@
<?define ComponentMainExecutableGUID = D102B8FA-059B-4ACC-9FA3-8C78C3B58EEF ?>
<?define ProductUpgradeCode = A1CC6134-E945-4399-BE36-EB0017FDF7CF ?>
- <Product Name='Mercurial' Id='*'
+ <Product Name='Mercurial $(var.Version)' Id='*'
UpgradeCode='$(var.ProductUpgradeCode)'
Language='1033' Codepage='1252' Version='$(var.Version)' Manufacturer='Matt Mackall and others.'>
@@ -83,12 +83,12 @@
<Directory Id="DesktopFolder" Name="Desktop" />
<Merge Id='VCRuntime' DiskId='1' Language='1033'
- SourceFile='C:\Program Files\Microsoft SDKs\Windows\v7.0\Redist\VC\microsoft.vcxx.crt.x86_msm.msm' />
+ SourceFile='$(var.VCRedistSrcDir)\microsoft.vcxx.crt.x86_msm.msm' />
<Merge Id='VCRuntimePolicy' DiskId='1' Language='1033'
- SourceFile='C:\Program Files\Microsoft SDKs\Windows\v7.0\Redist\VC\policy.x.xx.microsoft.vcxx.crt.x86_msm.msm' />
+ SourceFile='$(var.VCRedistSrcDir)\policy.x.xx.microsoft.vcxx.crt.x86_msm.msm' />
</Directory>
- <Feature Id='Complete' Title='Mercurial $(var.Version)' Description='The complete package'
+ <Feature Id='Complete' Title='Mercurial' Description='The complete package'
Display='expand' Level='1' ConfigurableDirectory='INSTALLDIR' >
<Feature Id='MainProgram' Title='Program' Description='Mercurial command line app'
Level='1' Absent='disallow' >
--- a/hgext/keyword.py Tue Mar 16 11:37:14 2010 -0300
+++ b/hgext/keyword.py Fri Mar 19 16:04:49 2010 -0500
@@ -162,16 +162,13 @@
Caveat: localrepository._link fails on Windows.'''
return self.match(path) and not 'l' in flagfunc(path)
- def overwrite(self, node, expand, files):
+ def overwrite(self, node, expand, candidates):
'''Overwrites selected files expanding/shrinking keywords.'''
ctx = self.repo[node]
mf = ctx.manifest()
if node is not None: # commit
- files = [f for f in ctx.files() if f in mf]
- notify = self.ui.debug
- else: # kwexpand/kwshrink
- notify = self.ui.note
- candidates = [f for f in files if self.iskwfile(f, ctx.flags)]
+ candidates = [f for f in ctx.files() if f in mf]
+ candidates = [f for f in candidates if self.iskwfile(f, ctx.flags)]
if candidates:
self.restrict = True # do not expand when reading
msg = (expand and _('overwriting %s expanding keywords\n')
@@ -189,7 +186,7 @@
else:
found = self.re_kw.search(data)
if found:
- notify(msg % f)
+ self.ui.note(msg % f)
self.repo.wwrite(f, data, mf.flags(f))
if node is None:
self.repo.dirstate.normal(f)
@@ -290,7 +287,6 @@
ui.write('%s = %s\n' % (k, v))
fn = 'demo.txt'
- branchname = 'demobranch'
tmpdir = tempfile.mkdtemp('', 'kwdemo.')
ui.note(_('creating temporary repository at %s\n') % tmpdir)
repo = localrepo.localrepository(ui, tmpdir, True)
@@ -326,35 +322,23 @@
uisetup(ui)
reposetup(ui, repo)
- for k, v in ui.configitems('extensions'):
- if k.endswith('keyword'):
- extension = '%s = %s' % (k, v)
- break
- ui.write('[extensions]\n%s\n' % extension)
+ ui.write('[extensions]\nkeyword =\n')
demoitems('keyword', ui.configitems('keyword'))
demoitems('keywordmaps', kwmaps.iteritems())
keywords = '$' + '$\n$'.join(sorted(kwmaps.keys())) + '$\n'
repo.wopener(fn, 'w').write(keywords)
repo.add([fn])
- path = repo.wjoin(fn)
- ui.note(_('\nkeywords written to %s:\n') % path)
+ ui.note(_('\nkeywords written to %s:\n') % fn)
ui.note(keywords)
- ui.note('\nhg -R "%s" branch "%s"\n' % (tmpdir, branchname))
- # silence branch command if not verbose
- quiet = ui.quiet
- ui.quiet = not ui.verbose
- commands.branch(ui, repo, branchname)
- ui.quiet = quiet
+ repo.dirstate.setbranch('demobranch')
for name, cmd in ui.configitems('hooks'):
if name.split('.', 1)[0].find('commit') > -1:
repo.ui.setconfig('hooks', name, '')
- ui.note(_('unhooked all commit hooks\n'))
msg = _('hg keyword configuration and expansion example')
- ui.note("hg -R '%s' ci -m '%s'\n" % (tmpdir, msg))
+ ui.note("hg ci -m '%s'\n" % msg)
repo.commit(text=msg)
ui.status(_('\n\tkeywords expanded\n'))
ui.write(repo.wread(fn))
- ui.debug('\nremoving temporary repository %s\n' % tmpdir)
shutil.rmtree(tmpdir, ignore_errors=True)
def expand(ui, repo, *pats, **opts):
--- a/hgext/mq.py Tue Mar 16 11:37:14 2010 -0300
+++ b/hgext/mq.py Fri Mar 19 16:04:49 2010 -0500
@@ -88,13 +88,11 @@
for line in file(pf):
line = line.rstrip()
- if line.startswith('diff --git'):
+ if (line.startswith('diff --git')
+ or (diffstart and line.startswith('+++ '))):
diffstart = 2
break
- if diffstart:
- if line.startswith('+++ '):
- diffstart = 2
- break
+ diffstart = 0 # reset
if line.startswith("--- "):
diffstart = 1
continue
--- a/hgext/patchbomb.py Tue Mar 16 11:37:14 2010 -0300
+++ b/hgext/patchbomb.py Fri Mar 19 16:04:49 2010 -0500
@@ -105,6 +105,10 @@
raise util.Abort(_('diffstat rejected'))
return s
+def introneeded(opts, number):
+ '''is an introductory message required?'''
+ return number > 1 or opts.get('intro') or opts.get('desc')
+
def makepatch(ui, repo, patch, opts, _charsets, idx, total, patchname=None):
desc = []
@@ -170,7 +174,7 @@
flag = ' ' + flag
subj = desc[0].strip().rstrip('. ')
- if total == 1 and not opts.get('intro'):
+ if not introneeded(opts, total):
subj = '[PATCH%s] %s' % (flag, opts.get('subject') or subj)
else:
tlen = len(str(total))
@@ -329,7 +333,7 @@
len(patches), name)
msgs.append(msg)
- if len(patches) > 1 or opts.get('intro'):
+ if introneeded(opts, len(patches)):
tlen = len(str(len(patches)))
flag = ' '.join(opts.get('flag'))
--- a/hgext/relink.py Tue Mar 16 11:37:14 2010 -0300
+++ b/hgext/relink.py Fri Mar 19 16:04:49 2010 -0500
@@ -116,6 +116,7 @@
CHUNKLEN = 65536
relinked = 0
savedbytes = 0
+ f = ''
pos = 0
total = len(files)
@@ -145,7 +146,7 @@
except OSError, inst:
ui.warn('%s: %s\n' % (tgt, str(inst)))
- ui.progress(_('relinking'), None, f, _(' files'), total)
+ ui.progress(_('relinking'), None)
ui.status(_('relinked %d files (%d bytes reclaimed)\n') %
(relinked, savedbytes))
--- a/mercurial/cmdutil.py Tue Mar 16 11:37:14 2010 -0300
+++ b/mercurial/cmdutil.py Fri Mar 19 16:04:49 2010 -0500
@@ -325,7 +325,7 @@
myscore = score(repo.wread(a))
if myscore >= bestscore:
copies[a] = (r, myscore)
- repo.ui.progress(_('searching'), None, total=len(removed))
+ repo.ui.progress(_('searching'), None)
for dest, v in copies.iteritems():
source, score = v
--- a/mercurial/filelog.py Tue Mar 16 11:37:14 2010 -0300
+++ b/mercurial/filelog.py Fri Mar 19 16:04:49 2010 -0500
@@ -33,9 +33,7 @@
def add(self, text, meta, transaction, link, p1=None, p2=None):
if meta or text.startswith('\1\n'):
- mt = ""
- if meta:
- mt = ["%s: %s\n" % (k, v) for k, v in sorted(meta.iteritems())]
+ mt = ["%s: %s\n" % (k, v) for k, v in sorted(meta.iteritems())]
text = "\1\n%s\1\n%s" % ("".join(mt), text)
return self.addrevision(text, transaction, link, p1, p2)
@@ -61,7 +59,7 @@
"""compare text with a given file revision"""
# for renames, we have to go the slow way
- if self.renamed(node):
+ if text.startswith('\1\n') or self.renamed(node):
t2 = self.read(node)
return t2 != text
--- a/mercurial/help.py Tue Mar 16 11:37:14 2010 -0300
+++ b/mercurial/help.py Fri Mar 19 16:04:49 2010 -0500
@@ -25,7 +25,7 @@
break
start = line[:3]
- if start == '\"\"\"' or start == "\'\'\'":
+ if start == '"""' or start == "'''":
line = line[3:]
while line:
if line.rstrip().endswith(start):
--- a/mercurial/hg.py Tue Mar 16 11:37:14 2010 -0300
+++ b/mercurial/hg.py Fri Mar 19 16:04:49 2010 -0500
@@ -209,6 +209,7 @@
src_repo = repository(ui, source)
else:
src_repo = source
+ branch = None
origsource = source = src_repo.url()
rev, checkout = addbranchrevs(src_repo, src_repo, branch, rev)
--- a/mercurial/localrepo.py Tue Mar 16 11:37:14 2010 -0300
+++ b/mercurial/localrepo.py Fri Mar 19 16:04:49 2010 -0500
@@ -1091,10 +1091,11 @@
rejected.append(f)
continue
if st.st_size > 10000000:
- self.ui.warn(_("%s: files over 10MB may cause memory and"
- " performance problems\n"
- "(use 'hg revert %s' to unadd the file)\n")
- % (f, f))
+ self.ui.warn(_("%s: up to %d MB of RAM may be required "
+ "to manage this file\n"
+ "(use 'hg revert %s' to cancel the "
+ "pending addition)\n")
+ % (f, 3 * st.st_size // 1000000, f))
if not (stat.S_ISREG(st.st_mode) or stat.S_ISLNK(st.st_mode)):
self.ui.warn(_("%s not added: only files and symlinks "
"supported currently\n") % f)
@@ -1395,7 +1396,7 @@
self.ui.debug("found new changesets starting at " +
" ".join([short(f) for f in fetch]) + "\n")
- self.ui.progress(_('searching'), None, unit=_('queries'))
+ self.ui.progress(_('searching'), None)
self.ui.debug("%d total queries\n" % reqcnt)
return base.keys(), list(fetch), heads
@@ -1828,7 +1829,7 @@
yield chnk
self.ui.progress(_('bundling changes'), cnt, unit=_('chunks'))
cnt += 1
- self.ui.progress(_('bundling changes'), None, unit=_('chunks'))
+ self.ui.progress(_('bundling changes'), None)
# Figure out which manifest nodes (of the ones we think might be
@@ -1856,7 +1857,7 @@
yield chnk
self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks'))
cnt += 1
- self.ui.progress(_('bundling manifests'), None, unit=_('chunks'))
+ self.ui.progress(_('bundling manifests'), None)
# These are no longer needed, dereference and toss the memory for
# them.
@@ -1905,7 +1906,7 @@
del msng_filenode_set[fname]
# Signal that no more groups are left.
yield changegroup.closechunk()
- self.ui.progress(_('bundling files'), None, unit=_('chunks'))
+ self.ui.progress(_('bundling files'), None)
if msng_cl_lst:
self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source)
@@ -1957,7 +1958,7 @@
self.ui.progress(_('bundling changes'), cnt, unit=_('chunks'))
cnt += 1
yield chnk
- self.ui.progress(_('bundling changes'), None, unit=_('chunks'))
+ self.ui.progress(_('bundling changes'), None)
mnfst = self.manifest
nodeiter = gennodelst(mnfst)
@@ -1966,7 +1967,7 @@
self.ui.progress(_('bundling manifests'), cnt, unit=_('chunks'))
cnt += 1
yield chnk
- self.ui.progress(_('bundling manifests'), None, unit=_('chunks'))
+ self.ui.progress(_('bundling manifests'), None)
cnt = 0
for fname in sorted(changedfiles):
@@ -1984,7 +1985,7 @@
_('bundling files'), cnt, item=fname, unit=_('chunks'))
cnt += 1
yield chnk
- self.ui.progress(_('bundling files'), None, unit=_('chunks'))
+ self.ui.progress(_('bundling files'), None)
yield changegroup.closechunk()
--- a/mercurial/patch.py Tue Mar 16 11:37:14 2010 -0300
+++ b/mercurial/patch.py Fri Mar 19 16:04:49 2010 -0500
@@ -178,7 +178,8 @@
# (this heuristic is borrowed from quilt)
diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |'
r'retrieving revision [0-9]+(\.[0-9]+)*$|'
- r'(---|\*\*\*)[ \t])', re.MULTILINE)
+ r'(---|\*\*\*)[ \t].*?'
+ r'^(\+\+\+|\*\*\*)[ \t])', re.MULTILINE|re.DOTALL)
fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
tmpfp = os.fdopen(fd, 'w')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-check-code Fri Mar 19 16:04:49 2010 -0500
@@ -0,0 +1,26 @@
+#!/bin/sh
+#cd `dirname $0`
+cat > correct.py <<EOF
+def toto(arg1, arg2):
+ del arg2
+ return (5 + 6, 9)
+EOF
+
+cat > wrong.py <<EOF
+def toto( arg1, arg2):
+ del(arg2)
+ return ( 5+6, 9)
+EOF
+
+cat > quote.py <<EOF
+# let's use quote in comments
+(''' ( 4x5 )
+but """\\''' and finally''',
+"""let's fool checkpatch""", '1+2',
+'"""', 42+1, """and
+( 4-1 ) """, "( 1+1 )\" and ")
+a, '\\\\\\\\', "\\\\\\" x-2", "c-1"
+EOF
+
+check_code=`dirname $0`/../contrib/check-code.py
+${check_code} ./wrong.py ./correct.py ./quote.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-check-code.out Fri Mar 19 16:04:49 2010 -0500
@@ -0,0 +1,13 @@
+./wrong.py:1:
+ > def toto( arg1, arg2):
+ gratuitous whitespace in () or []
+./wrong.py:2:
+ > del(arg2)
+ del isn't a function
+./wrong.py:3:
+ > return ( 5+6, 9)
+ missing whitespace in expression
+ gratuitous whitespace in () or []
+./quote.py:5:
+ > '"""', 42+1, """and
+ missing whitespace in expression
--- a/tests/test-import Tue Mar 16 11:37:14 2010 -0300
+++ b/tests/test-import Fri Mar 19 16:04:49 2010 -0500
@@ -375,6 +375,25 @@
hg parents -v
cd ..
+echo % '--- in commit message'
+hg init commitconfusion
+cd commitconfusion
+cat > a.patch <<EOF
+module: summary
+
+--- description
+
+diff --git a/a b/a
+new file mode 100644
+--- /dev/null
++++ b/a
+@@ -0,0 +1,1 @@
++a
+EOF
+hg import -d '0 0' a.patch
+hg parents -v
+cd ..
+
echo '% tricky header splitting'
cat > trickyheaders.patch <<EOF
From: User A <user@a>
--- a/tests/test-import.out Tue Mar 16 11:37:14 2010 -0300
+++ b/tests/test-import.out Fri Mar 19 16:04:49 2010 -0500
@@ -318,6 +318,17 @@
description
+% --- in commit message
+applying a.patch
+changeset: 0:f34d9187897d
+tag: tip
+user: test
+date: Thu Jan 01 00:00:00 1970 +0000
+files: a
+description:
+module: summary
+
+
% tricky header splitting
applying ../trickyheaders.patch
# HG changeset patch
--- a/tests/test-keyword.out Tue Mar 16 11:37:14 2010 -0300
+++ b/tests/test-keyword.out Fri Mar 19 16:04:49 2010 -0500
@@ -1,6 +1,6 @@
% hg kwdemo
[extensions]
-keyword =
+keyword =
[keyword]
demo.txt =
[keywordmaps]
@@ -21,7 +21,7 @@
$Revision: xxxxxxxxxxxx $
$Source: /TMP/demo.txt,v $
[extensions]
-keyword =
+keyword =
[keyword]
demo.txt =
[keywordmaps]
@@ -206,7 +206,7 @@
% custom keyword expansion
% try with kwdemo
[extensions]
-keyword =
+keyword =
[keyword]
* =
b = ignore
--- a/tests/test-mq Tue Mar 16 11:37:14 2010 -0300
+++ b/tests/test-mq Fri Mar 19 16:04:49 2010 -0500
@@ -86,6 +86,11 @@
hg init --mq
cd ..
+echo '% init --mq with repo path'
+hg init g
+hg init --mq g
+test -d g/.hg/patches/.hg && echo "ok" || echo "failed"
+
echo '% init --mq with nonexistent directory'
hg init --mq nonexistentdir
--- a/tests/test-mq-qimport Tue Mar 16 11:37:14 2010 -0300
+++ b/tests/test-mq-qimport Fri Mar 19 16:04:49 2010 -0500
@@ -43,6 +43,7 @@
First line of commit message.
More text in commit message.
+--- confuse the diff detection
diff --git a/x b/x
new file mode 100644
--- a/tests/test-mq.out Tue Mar 16 11:37:14 2010 -0300
+++ b/tests/test-mq.out Fri Mar 19 16:04:49 2010 -0500
@@ -91,6 +91,8 @@
B
% init --mq without repo
abort: There is no Mercurial repository here (.hg not found)
+% init --mq with repo path
+ok
% init --mq with nonexistent directory
abort: repository nonexistentdir not found!
% init --mq with bundle (non "local")
--- a/tests/test-patchbomb Tue Mar 16 11:37:14 2010 -0300
+++ b/tests/test-patchbomb Fri Mar 19 16:04:49 2010 -0500
@@ -126,6 +126,11 @@
hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
-r 2 | fixheaders
+echo "% test --desc without --intro for a single patch"
+echo foo > intro.text
+hg email --date '1970-1-1 0:1' -n --desc intro.text -f quux -t foo -c bar \
+ -s test -r 2 | fixheaders
+
echo "% test intro for multiple patches"
hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
-r 0:1 | fixheaders
--- a/tests/test-patchbomb.out Tue Mar 16 11:37:14 2010 -0300
+++ b/tests/test-patchbomb.out Fri Mar 19 16:04:49 2010 -0500
@@ -940,6 +940,52 @@
@@ -0,0 +1,1 @@
+c
+% test --desc without --intro for a single patch
+This patch series consists of 1 patches.
+
+
+Displaying [PATCH 0 of 1] test ...
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [PATCH 0 of 1] test
+Message-Id: <patchbomb.60@
+User-Agent: Mercurial-patchbomb
+Date: Thu, 01 Jan 1970 00:01:00 +0000
+From: quux
+To: foo
+Cc: bar
+
+foo
+
+Displaying [PATCH 1 of 1] c ...
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [PATCH 1 of 1] c
+X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
+Message-Id: <ff2c9fa2018b15fa74b3.61@
+In-Reply-To: <patchbomb.60@
+References: <patchbomb.60@
+User-Agent: Mercurial-patchbomb
+Date: Thu, 01 Jan 1970 00:01:01 +0000
+From: quux
+To: foo
+Cc: bar
+
+# HG changeset patch
+# User test
+# Date 3 0
+# Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
+# Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
+c
+
+diff -r 97d72e5f12c7 -r ff2c9fa2018b c
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/c Thu Jan 01 00:00:03 1970 +0000
+@@ -0,0 +1,1 @@
++c
+
% test intro for multiple patches
This patch series consists of 2 patches.