[PATCH 2 of 3] mq: refactor mq.patchheader

Steve Losh steve at stevelosh.com
Fri Feb 12 19:11:16 CST 2010


# HG changeset patch
# User Steve Losh <steve at stevelosh.com>
# Date 1265763661 18000
# Node ID 3c1eee3d90378bde9502bb2f7098f97bc67be6a9
# Parent  60564b40a8f6989fdb1b2997e4ce5334ffc4544c
mq: refactor mq.patchheader

This patch refactors the patchheader class in mq.py to be more understandable
and more robust when working with plain- and hg-style patch headers.

Some of the tests have also been updated to reflect the new, more consistent
ordering of the header fields.

diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -31,28 +31,38 @@
 avoid losing file mode changes, copy records, binary files or empty
 files creations or deletions. This behaviour can be configured with::
 
   [mq]
   git = auto/keep/yes/no
 
 If set to 'keep', mq will obey the [diff] section configuration while
 preserving existing git patches upon qrefresh. If set to 'yes' or
 'no', mq will override the [diff] section and always generate git or
 regular patches, possibly losing data in the second case.
+
+By default, mq will automatically use hg-style patch headers when creating
+new patches. This behavior can be changed with::
+
+  [mq]
+  plain = true
+
+If set to 'true', mq will use plain headers with only "Date" and "From"
+fields. For existing patches with headers the header format will always be
+preserved.
 '''
 
 from mercurial.i18n import _
 from mercurial.node import bin, hex, short, nullid, nullrev
 from mercurial.lock import release
 from mercurial import commands, cmdutil, hg, patch, util
 from mercurial import repair, extensions, url, error
-import os, sys, re, errno
+import os, sys, re, errno, itertools
 
 commands.norepo += " qclone"
 
 # Patch names looks like unix-file names.
 # They must be joinable with queue directory and result in the patch path.
 normname = util.normpath
 
 class statusentry(object):
     def __init__(self, rev, name=None):
         if not name:
@@ -61,216 +71,170 @@
                 self.rev, self.name = fields
             else:
                 self.rev, self.name = None, None
         else:
             self.rev, self.name = rev, name
 
     def __str__(self):
         return self.rev + ':' + self.name
 
 class patchheader(object):
-    def __init__(self, pf, plainmode=False):
-        def eatdiff(lines):
-            while lines:
-                l = lines[-1]
-                if (l.startswith("diff -") or
-                    l.startswith("Index:") or
-                    l.startswith("===========")):
-                    del lines[-1]
-                else:
-                    break
-        def eatempty(lines):
-            while lines:
-                l = lines[-1]
-                if re.match('\s*$', l):
-                    del lines[-1]
-                else:
-                    break
+    def __init__(self, pf=None, plain=False):
+        self.user = None
+        self.parent = None
+        self.date = None
+        self.format = plain and 'plain' or 'hg'
+        self.message = []
+        self._extrahgfields = []
 
-        message = []
-        comments = []
-        user = None
-        date = None
-        parent = None
-        format = None
-        subject = None
-        diffstart = 0
+        if pf:
+            self.parsepatch(pf)
 
-        for line in file(pf):
-            line = line.rstrip()
-            if line.startswith('diff --git'):
-                diffstart = 2
+    def parsepatch(self, pf):
+        """Parse a patch file and initialize this object with the header data.
+
+        If the format of the header can be determined the format attribute
+        will also be set.
+        """
+        def notdiffline(s):
+            return not (s.startswith("diff -") or
+                        s.startswith("Index:") or
+                        s.startswith("==========="))
+        pf = file(pf)
+        rawh = ''.join((itertools.takewhile(notdiffline, pf))).strip().splitlines()
+
+        try:
+            pf.next()
+            self.haspatch = True
+        except StopIteration:
+            self.haspatch = False
+
+        if not rawh:
+            # Nothing (or only whitespace) came before the diff.
+            return
+
+        if util.any(s.startswith('# HG changeset patch') for s in rawh):
+            # There's an hg-style patch somewhere, but there may be some text
+            # before it. It might be from an email.
+            # Eat the preceeding text and just parse the patch header.
+            while not rawh.pop(0).startswith('# HG changeset patch'):
+                pass
+            self.format = 'hg'
+            self._parsehgheader(rawh)
+        elif rawh[0].startswith('Date: ') or rawh[0].startswith('From: '):
+            self.format = 'plain'
+            self._parseplainheader(rawh)
+        else:
+            # No special headers come before the diff, but *something* did.
+            self.message = rawh
+
+    def _parsehgheader(self, rawh):
+        while rawh:
+            if rawh[0].startswith('# HG changeset patch'):
+                rawh.pop(0)
+            elif rawh[0].startswith('# User '):
+                self.user = rawh.pop(0).split(' ', 2)[-1]
+            elif rawh[0].startswith('# Date '):
+                self.date = rawh.pop(0).split(' ', 2)[-1]
+            elif rawh[0].startswith('# Parent '):
+                self.parent = rawh.pop(0).split(' ', 2)[-1]
+            elif rawh[0].startswith('# '):
+                # Stash the other hg patch header fields (like Node ID and
+                # Branch that export generates) away so they don't go in the
+                # commit message.
+                self._extrahgfields.append(rawh.pop(0))
+            else:
                 break
-            if diffstart:
-                if line.startswith('+++ '):
-                    diffstart = 2
+        message = '\n'.join(rawh).strip()
+        if message:
+            self.message = message.splitlines()
+
+    def _parseplainheader(self, rawh):
+        while rawh:
+            if rawh[0].startswith('Date: '):
+                self.date = rawh.pop(0).split(' ', 1)[-1]
+            elif rawh[0].startswith('From: '):
+                self.user = rawh.pop(0).split(' ', 1)[-1]
+            else:
                 break
-            if line.startswith("--- "):
-                diffstart = 1
-                continue
-            elif format == "hgpatch":
-                # parse values when importing the result of an hg export
-                if line.startswith("# User "):
-                    user = line[7:]
-                elif line.startswith("# Date "):
-                    date = line[7:]
-                elif line.startswith("# Parent "):
-                    parent = line[9:]
-                elif not line.startswith("# ") and line:
-                    message.append(line)
-                    format = None
-            elif line == '# HG changeset patch':
-                message = []
-                format = "hgpatch"
-            elif (format != "tagdone" and (line.startswith("Subject: ") or
-                                           line.startswith("subject: "))):
-                subject = line[9:]
-                format = "tag"
-            elif (format != "tagdone" and (line.startswith("From: ") or
-                                           line.startswith("from: "))):
-                user = line[6:]
-                format = "tag"
-            elif (format != "tagdone" and (line.startswith("Date: ") or
-                                           line.startswith("date: "))):
-                date = line[6:]
-                format = "tag"
-            elif format == "tag" and line == "":
-                # when looking for tags (subject: from: etc) they
-                # end once you find a blank line in the source
-                format = "tagdone"
-            elif message or line:
-                message.append(line)
-            comments.append(line)
+        message = '\n'.join(rawh).strip()
+        if message:
+            self.message = message.splitlines()
 
-        eatdiff(message)
-        eatdiff(comments)
-        eatempty(message)
-        eatempty(comments)
+    def _plainstr(self):
+        """Return a string of this header rendered as a plain-style header."""
+        hs = ''
+        if self.user:
+            hs += 'From: %s\n' % self.user
+        if self.date:
+            hs += 'Date: %s\n' % self.date
+        if self.message:
+            if hs:
+                hs += '\n'
+            hs += '%s\n' % '\n'.join(self.message).rstrip()
+        if hs:
+            hs += '\n'
+        return hs
 
-        # make sure message isn't empty
-        if format and format.startswith("tag") and subject:
-            message.insert(0, "")
-            message.insert(0, subject)
-
-        self.message = message
-        self.comments = comments
-        self.user = user
-        self.date = date
-        self.parent = parent
-        self.haspatch = diffstart > 1
-        self.plainmode = plainmode
-
-    def setuser(self, user):
-        if not self.updateheader(['From: ', '# User '], user):
-            try:
-                patchheaderat = self.comments.index('# HG changeset patch')
-                self.comments.insert(patchheaderat + 1, '# User ' + user)
-            except ValueError:
-                if self.plainmode or self._hasheader(['Date: ']):
-                    self.comments = ['From: ' + user] + self.comments
-                else:
-                    tmp = ['# HG changeset patch', '# User ' + user, '']
-                    self.comments = tmp + self.comments
-        self.user = user
-
-    def setdate(self, date):
-        if not self.updateheader(['Date: ', '# Date '], date):
-            try:
-                patchheaderat = self.comments.index('# HG changeset patch')
-                self.comments.insert(patchheaderat + 1, '# Date ' + date)
-            except ValueError:
-                if self.plainmode or self._hasheader(['From: ']):
-                    self.comments = ['Date: ' + date] + self.comments
-                else:
-                    tmp = ['# HG changeset patch', '# Date ' + date, '']
-                    self.comments = tmp + self.comments
-        self.date = date
-
-    def setparent(self, parent):
-        if not self.updateheader(['# Parent '], parent):
-            try:
-                patchheaderat = self.comments.index('# HG changeset patch')
-                self.comments.insert(patchheaderat + 1, '# Parent ' + parent)
-            except ValueError:
-                pass
-        self.parent = parent
-
-    def setmessage(self, message):
-        if self.comments:
-            self._delmsg()
-        self.message = [message]
-        self.comments += self.message
-
-    def updateheader(self, prefixes, new):
-        '''Update all references to a field in the patch header.
-        Return whether the field is present.'''
-        res = False
-        for prefix in prefixes:
-            for i in xrange(len(self.comments)):
-                if self.comments[i].startswith(prefix):
-                    self.comments[i] = prefix + new
-                    res = True
-                    break
-        return res
-
-    def _hasheader(self, prefixes):
-        '''Check if a header starts with any of the given prefixes.'''
-        for prefix in prefixes:
-            for comment in self.comments:
-                if comment.startswith(prefix):
-                    return True
-        return False
+    def _hgstr(self):
+        """Return a string of this header rendered as an hg-style header."""
+        hs = '# HG changeset patch\n'
+        if self.user:
+            hs += '# User %s\n' % self.user
+        if self.date:
+            hs += '# Date %s\n' % self.date
+        if self.parent:
+            hs += '# Parent %s\n' % self.parent
+        if self._extrahgfields:
+            hs += '\n'.join(self._extrahgfields) + '\n'
+        if self.message:
+            hs += '\n%s\n' % '\n'.join(self.message).rstrip()
+        hs += '\n'
+        return hs
 
     def __str__(self):
-        if not self.comments:
-            return ''
-        return '\n'.join(self.comments) + '\n\n'
+        """Return a string of this header in the appropriate format.
 
-    def _delmsg(self):
-        '''Remove existing message, keeping the rest of the comments fields.
-        If comments contains 'subject: ', message will prepend
-        the field and a blank line.'''
-        if self.message:
-            subj = 'subject: ' + self.message[0].lower()
-            for i in xrange(len(self.comments)):
-                if subj == self.comments[i].lower():
-                    del self.comments[i]
-                    self.message = self.message[2:]
-                    break
-        ci = 0
-        for mi in self.message:
-            while mi != self.comments[ci]:
-                ci += 1
-            del self.comments[ci]
+        For existing patches, the header format is preserved. For new patches
+        the format is determined by the mq.plain configuration option.
+
+        The format can also be set explicitly by setting the format
+        attribute of a patchheader object to 'plain' or 'hg'.
+        """
+        if self.format == 'plain':
+            return self._plainstr()
+        else:
+            return self._hgstr()
+
 
 class queue(object):
     def __init__(self, ui, path, patchdir=None):
+        self.plainmode = ui.configbool('mq', 'plain', False)
         self.basepath = path
         self.path = patchdir or os.path.join(path, "patches")
         self.opener = util.opener(self.path)
         self.ui = ui
         self.applied_dirty = 0
         self.series_dirty = 0
         self.series_path = "series"
         self.status_path = "status"
         self.guards_path = "guards"
         self.active_guards = None
         self.guards_dirty = False
         # Handle mq.git as a bool with extended values
         try:
             gitmode = ui.configbool('mq', 'git', None)
             if gitmode is None:
                 raise error.ConfigError()
             self.gitmode = gitmode and 'yes' or 'no'
         except error.ConfigError:
             self.gitmode = ui.config('mq', 'git', 'auto').lower()
-        self.plainmode = ui.configbool('mq', 'plain', False)
 
     @util.propertycache
     def applied(self):
         if os.path.exists(self.join(self.status_path)):
             lines = self.opener(self.status_path).read().splitlines()
             return [statusentry(l) for l in lines]
         return []
 
     @util.propertycache
     def full_series(self):
@@ -521,21 +485,21 @@
         self.strip(repo, n, update=False, backup='strip')
 
         ctx = repo[rev]
         ret = hg.merge(repo, rev)
         if ret:
             raise util.Abort(_("update returned %d") % ret)
         n = repo.commit(ctx.description(), ctx.user(), force=True)
         if n is None:
             raise util.Abort(_("repo commit failed"))
         try:
-            ph = patchheader(mergeq.join(patch), self.plainmode)
+            ph = patchheader(mergeq.join(patch), plain=self.plainmode)
         except:
             raise util.Abort(_("unable to read %s") % patch)
 
         diffopts = self.patchopts(diffopts, patch)
         patchf = self.opener(patch, "w")
         comments = str(ph)
         if comments:
             patchf.write(comments)
         self.printdiff(repo, diffopts, head, n, fp=patchf)
         patchf.close()
@@ -651,21 +615,21 @@
         n = None
         for patchname in series:
             pushable, reason = self.pushable(patchname)
             if not pushable:
                 self.explain_pushable(patchname, all_patches=True)
                 continue
             self.ui.status(_("applying %s\n") % patchname)
             pf = os.path.join(patchdir, patchname)
 
             try:
-                ph = patchheader(self.join(patchname), self.plainmode)
+                ph = patchheader(self.join(patchname), plain=self.plainmode)
             except:
                 self.ui.warn(_("unable to read %s\n") % patchname)
                 err = 1
                 break
 
             message = ph.message
             if not message:
                 message = "imported patch %s\n" % patchname
             else:
                 if list:
@@ -843,50 +807,43 @@
         if len(repo[None].parents()) > 1:
             raise util.Abort(_('cannot manage merge changesets'))
         commitfiles = m + a + r
         self.check_toppatch(repo)
         insert = self.full_series_end()
         wlock = repo.wlock()
         try:
             # if patch file write fails, abort early
             p = self.opener(patchfn, "w")
             try:
-                if self.plainmode:
-                    if user:
-                        p.write("From: " + user + "\n")
-                        if not date:
-                            p.write("\n")
-                    if date:
-                        p.write("Date: %d %d\n\n" % date)
-                else:
-                    p.write("# HG changeset patch\n")
-                    p.write("# Parent "
-                            + hex(repo[None].parents()[0].node()) + "\n")
-                    if user:
-                        p.write("# User " + user + "\n")
-                    if date:
-                        p.write("# Date %s %s\n\n" % date)
                 if hasattr(msg, '__call__'):
                     msg = msg()
                 commitmsg = msg and msg or ("[mq]: %s" % patchfn)
                 n = repo.commit(commitmsg, user, date, match=match, force=True)
                 if n is None:
                     raise util.Abort(_("repo commit failed"))
                 try:
                     self.full_series[insert:insert] = [patchfn]
                     self.applied.append(statusentry(hex(n), patchfn))
                     self.parse_series()
                     self.series_dirty = 1
                     self.applied_dirty = 1
+
+                    ph = patchheader(plain=self.plainmode)
+                    if user:
+                        ph.user = user
+                    if date:
+                        ph.date = '%d %d' % date
                     if msg:
-                        msg = msg + "\n\n"
-                        p.write(msg)
+                        ph.message = msg.splitlines()
+                    ph.parent = hex(repo[None].parents()[0].node())
+                    p.write(str(ph))
+
                     if commitfiles:
                         parent = self.qparents(repo, n)
                         chunks = patch.diff(repo, node1=parent, node2=n,
                                             match=match, opts=diffopts)
                         for chunk in chunks:
                             p.write(chunk)
                     p.close()
                     wlock.release()
                     wlock = None
                     r = self.qrepo()
@@ -1221,48 +1178,48 @@
         self.printdiff(repo, diffopts, node1, node2, files=pats, opts=opts)
 
     def refresh(self, repo, pats=None, **opts):
         if len(self.applied) == 0:
             self.ui.write(_("no patches applied\n"))
             return 1
         msg = opts.get('msg', '').rstrip()
         newuser = opts.get('user')
         newdate = opts.get('date')
         if newdate:
-            newdate = '%d %d' % util.parsedate(newdate)
+            newdate = util.parsedate(newdate)
         wlock = repo.wlock()
 
         try:
             self.check_toppatch(repo)
             (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name)
             top = bin(top)
             if repo.changelog.heads(top) != [top]:
                 raise util.Abort(_("cannot refresh a revision with children"))
 
             cparents = repo.changelog.parents(top)
             patchparent = self.qparents(repo, top)
-            ph = patchheader(self.join(patchfn), self.plainmode)
             diffopts = self.diffopts({'git': opts.get('git')}, patchfn)
+            ph = patchheader(self.join(patchfn), plain=self.plainmode)
+            if newuser:
+                ph.user = newuser
+            if newdate:
+                ph.date = '%d %d' % newdate
             if msg:
-                ph.setmessage(msg)
-            if newuser:
-                ph.setuser(newuser)
-            if newdate:
-                ph.setdate(newdate)
-            ph.setparent(hex(patchparent))
+                ph.message = msg.splitlines()
+            ph.parent = hex(patchparent)
 
             # only commit new patch when write is complete
             patchf = self.opener(patchfn, 'w', atomictemp=True)
 
-            comments = str(ph)
-            if comments:
-                patchf.write(comments)
+            header = str(ph)
+            if header:
+                patchf.write(header)
 
             # update the dirstate in place, strip off the qtip commit
             # and then commit.
             #
             # this should really read:
             #   mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
             # but we do it backwards to take advantage of manifest/chlog
             # caching against the next repo.status call
             mm, aa, dd, aa2 = repo.status(patchparent, top)[:4]
             changes = repo.changelog.read(top)
@@ -1426,21 +1383,21 @@
             pushable, reason = self.pushable(i)
             if pushable:
                 unapplied.append((i, self.series[i]))
             self.explain_pushable(i)
         return unapplied
 
     def qseries(self, repo, missing=None, start=0, length=None, status=None,
                 summary=False):
         def displayname(pfx, patchname):
             if summary:
-                ph = patchheader(self.join(patchname), self.plainmode)
+                ph = patchheader(self.join(patchname))
                 msg = ph.message and ph.message[0] or ''
                 if self.ui.interactive():
                     width = util.termwidth() - len(pfx) - len(patchname) - 2
                     if width > 0:
                         msg = util.ellipsis(msg, width)
                     else:
                         msg = ''
                 msg = "%s%s: %s" % (pfx, patchname, msg)
             else:
                 msg = pfx + patchname
@@ -2032,21 +1989,21 @@
     """
     q = repo.mq
     message = cmdutil.logmessage(opts)
     if opts['edit']:
         if not q.applied:
             ui.write(_("no patches applied\n"))
             return 1
         if message:
             raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
         patch = q.applied[-1].name
-        ph = patchheader(q.join(patch), q.plainmode)
+        ph = patchheader(q.join(patch))
         message = ui.edit('\n'.join(ph.message), ph.user or ui.username())
     setupheaderopts(ui, opts)
     ret = q.refresh(repo, pats, msg=message, **opts)
     q.save_dirty()
     return ret
 
 def diff(ui, repo, *pats, **opts):
     """diff of the current patch and subsequent modifications
 
     Shows a diff which includes the current patch as well as any
@@ -2094,31 +2051,31 @@
     for f in files:
         p = q.lookup(f)
         if p in patches or p == parent:
             ui.warn(_('Skipping already folded patch %s') % p)
         if q.isapplied(p):
             raise util.Abort(_('qfold cannot fold already applied patch %s') % p)
         patches.append(p)
 
     for p in patches:
         if not message:
-            ph = patchheader(q.join(p), q.plainmode)
+            ph = patchheader(q.join(p))
             if ph.message:
                 messages.append(ph.message)
         pf = q.join(p)
         (patchsuccess, files, fuzz) = q.patch(repo, pf)
         if not patchsuccess:
             raise util.Abort(_('Error folding patch %s') % p)
         patch.updatedir(ui, repo, files)
 
     if not message:
-        ph = patchheader(q.join(parent), q.plainmode)
+        ph = patchheader(q.join(parent))
         message, user = ph.message, ph.user
         for msg in messages:
             message.append('* * *')
             message.extend(msg)
         message = '\n'.join(message)
 
     if opts['edit']:
         message = ui.edit(message, user or ui.username())
 
     diffopts = q.patchopts(q.diffopts(), *patches)
@@ -2187,21 +2144,21 @@
     """print the header of the topmost or specified patch"""
     q = repo.mq
 
     if patch:
         patch = q.lookup(patch)
     else:
         if not q.applied:
             ui.write('no patches applied\n')
             return 1
         patch = q.lookup('qtip')
-    ph = patchheader(q.join(patch), q.plainmode)
+    ph = patchheader(q.join(patch))
 
     ui.write('\n'.join(ph.message) + '\n')
 
 def lastsavename(path):
     (directory, base) = os.path.split(path)
     names = os.listdir(directory)
     namere = re.compile("%s.([0-9]+)" % base)
     maxindex = None
     maxname = None
     for f in names:
diff --git a/tests/test-mq-eol.out b/tests/test-mq-eol.out
--- a/tests/test-mq-eol.out
+++ b/tests/test-mq-eol.out
@@ -14,20 +14,23 @@
 % invalid eol
 applying eol.diff
 patch failed, unable to continue (try -v)
 patch failed, rejects left in working dir
 errors during apply, please fix and refresh eol.diff
 popping eol.diff
 patch queue now empty
 % force LF
 applying eol.diff
 now at: eol.diff
+# HG changeset patch<LF>
+# Parent 0d0bf99a8b7a3842c6f8ef09e34f69156c4bd9d0<LF>
+<LF>
 test message<LF>
 <LF>
 diff -r 0d0bf99a8b7a a<LF>
 --- a/a<LF>
 +++ b/a<LF>
 @@ -1,5 +1,5 @@<LF>
 -a<LF>
 -b<LF>
 -c<LF>
 -d<LF>
diff --git a/tests/test-mq-git b/tests/test-mq-git
--- a/tests/test-mq-git
+++ b/tests/test-mq-git
@@ -1,19 +1,21 @@
 #!/bin/sh
 
 # Test the plumbing of mq.git option
 # Automatic upgrade itself is tested elsewhere.
 
 echo "[extensions]" >> $HGRCPATH
 echo "mq=" >> $HGRCPATH
 echo "[diff]" >> $HGRCPATH
 echo "nodates=1" >> $HGRCPATH
+echo "[mq]" >> $HGRCPATH
+echo "plain=true" >> $HGRCPATH
 
 hg init repo-auto
 cd repo-auto
 echo '% git=auto: regular patch creation'
 echo a > a
 hg add a
 hg qnew -d '0 0' -f adda
 cat .hg/patches/adda
 echo '% git=auto: git patch creation with copy'
 hg cp a b
diff --git a/tests/test-mq-git.out b/tests/test-mq-git.out
--- a/tests/test-mq-git.out
+++ b/tests/test-mq-git.out
@@ -1,109 +1,89 @@
 % git=auto: regular patch creation
-# HG changeset patch
-# Parent 0000000000000000000000000000000000000000
-# Date 0 0
+Date: 0 0
 
 diff -r 000000000000 -r ef8dafc9fa4c a
 --- /dev/null
 +++ b/a
 @@ -0,0 +1,1 @@
 +a
 % git=auto: git patch creation with copy
-# HG changeset patch
-# Parent ef8dafc9fa4caff80f6e243eb0171bcd60c455b4
-# Date 0 0
+Date: 0 0
 
 diff --git a/a b/b
 copy from a
 copy to b
 % git=auto: git patch when using --git
-# HG changeset patch
-# Parent 2962f232b49d41ebc26c591ec8d556724be213ab
-# Date 0 0
+Date: 0 0
 
 diff --git a/regular b/regular
 new file mode 100644
 --- /dev/null
 +++ b/regular
 @@ -0,0 +1,1 @@
 +regular
 % git=auto: regular patch after qrefresh without --git
-# HG changeset patch
-# Parent 2962f232b49d41ebc26c591ec8d556724be213ab
-# Date 0 0
+Date: 0 0
 
 diff -r 2962f232b49d regular
 --- /dev/null
 +++ b/regular
 @@ -0,0 +1,1 @@
 +regular
 % git=keep: git patch with --git
-# HG changeset patch
-# Parent 0000000000000000000000000000000000000000
-# Date 0 0
+Date: 0 0
 
 diff --git a/a b/a
 new file mode 100644
 --- /dev/null
 +++ b/a
 @@ -0,0 +1,1 @@
 +a
 % git=keep: git patch after qrefresh without --git
-# HG changeset patch
-# Parent 0000000000000000000000000000000000000000
-# Date 0 0
+Date: 0 0
 
 diff --git a/a b/a
 new file mode 100644
 --- /dev/null
 +++ b/a
 @@ -0,0 +1,2 @@
 +a
 +a
 % git=yes: git patch
-# HG changeset patch
-# Parent 0000000000000000000000000000000000000000
-# Date 0 0
+Date: 0 0
 
 diff --git a/a b/a
 new file mode 100644
 --- /dev/null
 +++ b/a
 @@ -0,0 +1,1 @@
 +a
 % git=yes: git patch after qrefresh
-# HG changeset patch
-# Parent 0000000000000000000000000000000000000000
-# Date 0 0
+Date: 0 0
 
 diff --git a/a b/a
 new file mode 100644
 --- /dev/null
 +++ b/a
 @@ -0,0 +1,2 @@
 +a
 +a
 % git=no: regular patch with copy
-# HG changeset patch
-# Parent ef8dafc9fa4caff80f6e243eb0171bcd60c455b4
-# Date 0 0
+Date: 0 0
 
 diff -r ef8dafc9fa4c -r 110cde11d262 b
 --- /dev/null
 +++ b/b
 @@ -0,0 +1,1 @@
 +a
 % git=no: regular patch after qrefresh with copy
-# HG changeset patch
-# Parent ef8dafc9fa4caff80f6e243eb0171bcd60c455b4
-# Date 0 0
+Date: 0 0
 
 diff -r ef8dafc9fa4c b
 --- /dev/null
 +++ b/b
 @@ -0,0 +1,1 @@
 +a
 diff -r ef8dafc9fa4c c
 --- /dev/null
 +++ b/c
 @@ -0,0 +1,1 @@
diff --git a/tests/test-mq-header-date.out b/tests/test-mq-header-date.out
--- a/tests/test-mq-header-date.out
+++ b/tests/test-mq-header-date.out
@@ -107,20 +107,21 @@
 diff -r ... 4
 --- /dev/null
 +++ b/4
 @@ -0,0 +1,1 @@
 +4
 2: Four - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 ==== qref -d
 Date: 9 0
+
 Four
 
 diff -r ... 4
 --- /dev/null
 +++ b/4
 @@ -0,0 +1,1 @@
 +4
 2: Four - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
@@ -130,35 +131,35 @@
 popping 5.patch
 now at: 3.patch
 # HG changeset patch
 # Date 10 0
 2: imported patch 5.patch - test - 10.00
 1: Three (again) - test - 8.00
 0: [mq]: 1.patch - test - 4.00
 ==== hg qref
 adding 5
 # HG changeset patch
+# Date 10 0
 # Parent 
-# Date 10 0
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 2: [mq]: 5.patch - test - 10.00
 1: Three (again) - test - 8.00
 0: [mq]: 1.patch - test - 4.00
 ==== hg qref -d
 # HG changeset patch
+# Date 11 0
 # Parent 
-# Date 11 0
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 2: [mq]: 5.patch - test - 11.00
 1: Three (again) - test - 8.00
 0: [mq]: 1.patch - test - 4.00
 ==== qnew with plain header
@@ -205,22 +206,22 @@
 diff -r ... 6
 --- /dev/null
 +++ b/6
 @@ -0,0 +1,1 @@
 +6
 3: [mq]: 6.patch - jane
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 ==== qref -d
+From: jane
 Date: 12 0
-From: jane
 
 diff -r ... 6
 --- /dev/null
 +++ b/6
 @@ -0,0 +1,1 @@
 +6
 3: [mq]: 6.patch - jane
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
@@ -258,22 +259,22 @@
 --- /dev/null
 +++ b/8
 @@ -0,0 +1,1 @@
 +8
 4: [mq]: 8.patch - test
 3: [mq]: 7.patch - john
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 ==== qref -u -d
+From: john
 Date: 14 0
-From: john
 
 diff -r ... 8
 --- /dev/null
 +++ b/8
 @@ -0,0 +1,1 @@
 +8
 4: [mq]: 8.patch - john
 3: [mq]: 7.patch - john
 2: [mq]: 5.patch - test
 1: Three (again) - test
@@ -288,22 +289,23 @@
 --- /dev/null
 +++ b/9
 @@ -0,0 +1,1 @@
 +9
 4: Nine - test
 3: [mq]: 7.patch - john
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 ==== qref -u -d
+From: john
 Date: 15 0
-From: john
+
 Nine
 
 diff -r ... 9
 --- /dev/null
 +++ b/9
 @@ -0,0 +1,1 @@
 +9
 4: Nine - john
 3: [mq]: 7.patch - john
 2: [mq]: 5.patch - test
@@ -323,40 +325,40 @@
 applying 7.patch
 now at: 7.patch
 3: imported patch 7.patch - john - 13.00
 2: imported patch 5.patch - test - 11.00
 1: Three (again) - test - 8.00
 0: imported patch 1.patch - test - 4.00
 ======= hg headers
 ==== init
 ==== qnew -d
 # HG changeset patch
+# Date 3 0
 # Parent 
-# Date 3 0
 
 0: [mq]: 1.patch - test - 3.00
 ==== qref
 adding 1
 # HG changeset patch
+# Date 3 0
 # Parent 
-# Date 3 0
 
 diff -r ... 1
 --- /dev/null
 +++ b/1
 @@ -0,0 +1,1 @@
 +1
 0: [mq]: 1.patch - test - 3.00
 ==== qref -d
 # HG changeset patch
+# Date 4 0
 # Parent 
-# Date 4 0
 
 diff -r ... 1
 --- /dev/null
 +++ b/1
 @@ -0,0 +1,1 @@
 +1
 0: [mq]: 1.patch - test - 4.00
 ==== qnew
 adding 2
 # HG changeset patch
@@ -378,102 +380,104 @@
 --- /dev/null
 +++ b/2
 @@ -0,0 +1,1 @@
 +2
 1: [mq]: 2.patch - test
 0: [mq]: 1.patch - test
 popping 2.patch
 now at: 1.patch
 ==== qnew -d -m
 # HG changeset patch
+# Date 6 0
 # Parent 
-# Date 6 0
 
 Three
 
 1: Three - test - 6.00
 0: [mq]: 1.patch - test - 4.00
 ==== qref
 adding 3
 # HG changeset patch
+# Date 6 0
 # Parent 
-# Date 6 0
 
 Three
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 1: Three - test - 6.00
 0: [mq]: 1.patch - test - 4.00
 ==== qref -m
 # HG changeset patch
+# Date 6 0
 # Parent 
-# Date 6 0
 
 Drei
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 1: Drei - test - 6.00
 0: [mq]: 1.patch - test - 4.00
 ==== qref -d
 # HG changeset patch
+# Date 7 0
 # Parent 
-# Date 7 0
 
 Drei
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 1: Drei - test - 7.00
 0: [mq]: 1.patch - test - 4.00
 ==== qref -d -m
 # HG changeset patch
+# Date 8 0
 # Parent 
-# Date 8 0
 
 Three (again)
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 1: Three (again) - test - 8.00
 0: [mq]: 1.patch - test - 4.00
 ==== qnew -m
 adding 4
 # HG changeset patch
 # Parent 
+
 Four
 
 diff -r ... 4
 --- /dev/null
 +++ b/4
 @@ -0,0 +1,1 @@
 +4
 2: Four - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 ==== qref -d
 # HG changeset patch
 # Date 9 0
 # Parent 
+
 Four
 
 diff -r ... 4
 --- /dev/null
 +++ b/4
 @@ -0,0 +1,1 @@
 +4
 2: Four - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
@@ -483,35 +487,35 @@
 popping 5.patch
 now at: 3.patch
 # HG changeset patch
 # Date 10 0
 2: imported patch 5.patch - test - 10.00
 1: Three (again) - test - 8.00
 0: [mq]: 1.patch - test - 4.00
 ==== hg qref
 adding 5
 # HG changeset patch
+# Date 10 0
 # Parent 
-# Date 10 0
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 2: [mq]: 5.patch - test - 10.00
 1: Three (again) - test - 8.00
 0: [mq]: 1.patch - test - 4.00
 ==== hg qref -d
 # HG changeset patch
+# Date 11 0
 # Parent 
-# Date 11 0
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 2: [mq]: 5.patch - test - 11.00
 1: Three (again) - test - 8.00
 0: [mq]: 1.patch - test - 4.00
 ==== qnew with plain header
@@ -547,69 +551,69 @@
 +6
 3: [mq]: 6.patch - test - 13.00
 2: [mq]: 5.patch - test - 11.00
 1: Three (again) - test - 8.00
 0: [mq]: 1.patch - test - 4.00
 popping 6.patch
 now at: 5.patch
 ==== qnew -u
 adding 6
 # HG changeset patch
+# User jane
 # Parent 
-# User jane
 
 diff -r ... 6
 --- /dev/null
 +++ b/6
 @@ -0,0 +1,1 @@
 +6
 3: [mq]: 6.patch - jane
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 ==== qref -d
 # HG changeset patch
+# User jane
 # Date 12 0
 # Parent 
-# User jane
 
 diff -r ... 6
 --- /dev/null
 +++ b/6
 @@ -0,0 +1,1 @@
 +6
 3: [mq]: 6.patch - jane
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 popping 6.patch
 now at: 5.patch
 ==== qnew -d
 adding 7
 # HG changeset patch
+# Date 13 0
 # Parent 
-# Date 13 0
 
 diff -r ... 7
 --- /dev/null
 +++ b/7
 @@ -0,0 +1,1 @@
 +7
 3: [mq]: 7.patch - test
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 ==== qref -u
 # HG changeset patch
 # User john
+# Date 13 0
 # Parent 
-# Date 13 0
 
 diff -r ... 7
 --- /dev/null
 +++ b/7
 @@ -0,0 +1,1 @@
 +7
 3: [mq]: 7.patch - john - 13.00
 2: [mq]: 5.patch - test - 11.00
 1: Three (again) - test - 8.00
 0: [mq]: 1.patch - test - 4.00
@@ -623,57 +627,59 @@
 +++ b/8
 @@ -0,0 +1,1 @@
 +8
 4: [mq]: 8.patch - test
 3: [mq]: 7.patch - john
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 ==== qref -u -d
 # HG changeset patch
+# User john
 # Date 14 0
-# User john
 # Parent 
 
 diff -r ... 8
 --- /dev/null
 +++ b/8
 @@ -0,0 +1,1 @@
 +8
 4: [mq]: 8.patch - john
 3: [mq]: 7.patch - john
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 popping 8.patch
 now at: 7.patch
 ==== qnew -m
 adding 9
 # HG changeset patch
 # Parent 
+
 Nine
 
 diff -r ... 9
 --- /dev/null
 +++ b/9
 @@ -0,0 +1,1 @@
 +9
 4: Nine - test
 3: [mq]: 7.patch - john
 2: [mq]: 5.patch - test
 1: Three (again) - test
 0: [mq]: 1.patch - test
 ==== qref -u -d
 # HG changeset patch
+# User john
 # Date 15 0
-# User john
 # Parent 
+
 Nine
 
 diff -r ... 9
 --- /dev/null
 +++ b/9
 @@ -0,0 +1,1 @@
 +9
 4: Nine - john
 3: [mq]: 7.patch - john
 2: [mq]: 5.patch - test
diff --git a/tests/test-mq-header-from.out b/tests/test-mq-header-from.out
--- a/tests/test-mq-header-from.out
+++ b/tests/test-mq-header-from.out
@@ -111,20 +111,21 @@
 --- /dev/null
 +++ b/4of
 @@ -0,0 +1,1 @@
 +4 t
 3: Four - test
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref -u
 From: jane
+
 Four
 
 diff -r ... 4of
 --- /dev/null
 +++ b/4of
 @@ -0,0 +1,1 @@
 +4 t
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
@@ -136,52 +137,52 @@
 # HG changeset patch
 # User johndoe
 4: imported patch 5.patch - johndoe
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== hg qref
 adding 5
 # HG changeset patch
+# User johndoe
 # Parent 
-# User johndoe
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 4: [mq]: 5.patch - johndoe
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== hg qref -U
 # HG changeset patch
+# User test
 # Parent 
-# User test
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 4: [mq]: 5.patch - test
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== hg qref -u
 # HG changeset patch
+# User johndeere
 # Parent 
-# User johndeere
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 4: [mq]: 5.patch - johndeere
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
@@ -259,39 +260,40 @@
 5: imported patch 6.patch - johndeere
 4: imported patch 5.patch - johndeere
 3: Four - jane
 2: Three (again) - maria
 1: imported patch 2.patch - jane
 0: imported patch 1.patch - mary
 ======= hg headers
 ==== init
 ==== qnew -U
 # HG changeset patch
+# User test
 # Parent 
-# User test
+
 0: [mq]: 1.patch - test
 ==== qref
 adding 1
 # HG changeset patch
+# User test
 # Parent 
-# User test
 
 diff -r ... 1
 --- /dev/null
 +++ b/1
 @@ -0,0 +1,1 @@
 +1
 0: [mq]: 1.patch - test
 ==== qref -u
 # HG changeset patch
+# User mary
 # Parent 
-# User mary
 
 diff -r ... 1
 --- /dev/null
 +++ b/1
 @@ -0,0 +1,1 @@
 +1
 0: [mq]: 1.patch - mary
 ==== qnew
 adding 2
 # HG changeset patch
@@ -311,103 +313,110 @@
 
 diff -r ... 2
 --- /dev/null
 +++ b/2
 @@ -0,0 +1,1 @@
 +2
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qnew -U -m
 # HG changeset patch
+# User test
 # Parent 
-# User test
+
 Three
 
 2: Three - test
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref
 adding 3
 # HG changeset patch
+# User test
 # Parent 
-# User test
+
 Three
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 2: Three - test
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref -m
 # HG changeset patch
+# User test
 # Parent 
-# User test
+
 Drei
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 2: Drei - test
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref -u
 # HG changeset patch
+# User mary
 # Parent 
-# User mary
+
 Drei
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 2: Drei - mary
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref -u -m
 # HG changeset patch
+# User maria
 # Parent 
-# User maria
+
 Three (again)
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qnew -m
 adding 4of
 # HG changeset patch
 # Parent 
+
 Four
 
 diff -r ... 4of
 --- /dev/null
 +++ b/4of
 @@ -0,0 +1,1 @@
 +4 t
 3: Four - test
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref -u
 # HG changeset patch
 # User jane
 # Parent 
+
 Four
 
 diff -r ... 4of
 --- /dev/null
 +++ b/4of
 @@ -0,0 +1,1 @@
 +4 t
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
@@ -419,52 +428,52 @@
 # HG changeset patch
 # User johndoe
 4: imported patch 5.patch - johndoe
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== hg qref
 adding 5
 # HG changeset patch
+# User johndoe
 # Parent 
-# User johndoe
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 4: [mq]: 5.patch - johndoe
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== hg qref -U
 # HG changeset patch
+# User test
 # Parent 
-# User test
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 4: [mq]: 5.patch - test
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== hg qref -u
 # HG changeset patch
+# User johndeere
 # Parent 
-# User johndeere
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 4: [mq]: 5.patch - johndeere
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
@@ -541,39 +550,40 @@
 now at: 6.patch
 5: imported patch 6.patch - johndeere
 4: imported patch 5.patch - johndeere
 3: Four - jane
 2: Three (again) - maria
 1: imported patch 2.patch - jane
 0: imported patch 1.patch - mary
 ==== init
 ==== qnew -U
 # HG changeset patch
+# User test
 # Parent 
-# User test
+
 0: [mq]: 1.patch - test
 ==== qref
 adding 1
 # HG changeset patch
+# User test
 # Parent 
-# User test
 
 diff -r ... 1
 --- /dev/null
 +++ b/1
 @@ -0,0 +1,1 @@
 +1
 0: [mq]: 1.patch - test
 ==== qref -u
 # HG changeset patch
+# User mary
 # Parent 
-# User mary
 
 diff -r ... 1
 --- /dev/null
 +++ b/1
 @@ -0,0 +1,1 @@
 +1
 0: [mq]: 1.patch - mary
 ==== qnew
 adding 2
 # HG changeset patch
@@ -593,103 +603,110 @@
 
 diff -r ... 2
 --- /dev/null
 +++ b/2
 @@ -0,0 +1,1 @@
 +2
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qnew -U -m
 # HG changeset patch
+# User test
 # Parent 
-# User test
+
 Three
 
 2: Three - test
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref
 adding 3
 # HG changeset patch
+# User test
 # Parent 
-# User test
+
 Three
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 2: Three - test
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref -m
 # HG changeset patch
+# User test
 # Parent 
-# User test
+
 Drei
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 2: Drei - test
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref -u
 # HG changeset patch
+# User mary
 # Parent 
-# User mary
+
 Drei
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 2: Drei - mary
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref -u -m
 # HG changeset patch
+# User maria
 # Parent 
-# User maria
+
 Three (again)
 
 diff -r ... 3
 --- /dev/null
 +++ b/3
 @@ -0,0 +1,1 @@
 +3
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qnew -m
 adding 4of
 # HG changeset patch
 # Parent 
+
 Four
 
 diff -r ... 4of
 --- /dev/null
 +++ b/4of
 @@ -0,0 +1,1 @@
 +4 t
 3: Four - test
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== qref -u
 # HG changeset patch
 # User jane
 # Parent 
+
 Four
 
 diff -r ... 4of
 --- /dev/null
 +++ b/4of
 @@ -0,0 +1,1 @@
 +4 t
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
@@ -701,52 +718,52 @@
 # HG changeset patch
 # User johndoe
 4: imported patch 5.patch - johndoe
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== hg qref
 adding 5
 # HG changeset patch
+# User johndoe
 # Parent 
-# User johndoe
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 4: [mq]: 5.patch - johndoe
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== hg qref -U
 # HG changeset patch
+# User test
 # Parent 
-# User test
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 4: [mq]: 5.patch - test
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
 0: [mq]: 1.patch - mary
 ==== hg qref -u
 # HG changeset patch
+# User johndeere
 # Parent 
-# User johndeere
 
 diff -r ... 5
 --- /dev/null
 +++ b/5
 @@ -0,0 +1,1 @@
 +5
 4: [mq]: 5.patch - johndeere
 3: Four - jane
 2: Three (again) - maria
 1: [mq]: 2.patch - jane
diff --git a/tests/test-mq-merge b/tests/test-mq-merge
--- a/tests/test-mq-merge
+++ b/tests/test-mq-merge
@@ -11,20 +11,21 @@
 {
     if [ -f .hg/store/undo ]; then
 	echo ".hg/store/undo still exists after $1"
     fi
 }
 
 echo "[extensions]" >> $HGRCPATH
 echo "mq =" >> $HGRCPATH
 echo "[mq]" >> $HGRCPATH
 echo "git = keep" >> $HGRCPATH
+echo "plain = true" >> $HGRCPATH
 
 # Commit two dummy files in "init" changeset
 hg init t
 cd t
 echo a > a
 echo b > b
 hg ci -Am init
 hg tag -l init
 
 # Create a patch removing a
diff --git a/tests/test-mq-merge.out b/tests/test-mq-merge.out
--- a/tests/test-mq-merge.out
+++ b/tests/test-mq-merge.out
@@ -27,23 +27,20 @@
 1 out of 1 hunks FAILED -- saving rejects to file a.rej
 patch failed, unable to continue (try -v)
 patch failed, rejects left in working dir
 patch didn't work out, merging patcha
 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
 applying patcha2
 now at: patcha2
 % check patcha is still a git patch
-# HG changeset patch
-# Parent d3873e73d99ef67873dac33fbcc66268d5d2b6f4
-
 diff --git a/a b/a
 --- a/a
 +++ b/a
 @@ -1,1 +1,2 @@
 -b
 +a
 +c
 diff --git a/a b/aa
 copy from a
 copy to aa
diff --git a/tests/test-mq-qnew.out b/tests/test-mq-qnew.out
--- a/tests/test-mq-qnew.out
+++ b/tests/test-mq-qnew.out
@@ -56,44 +56,47 @@
 uncommitted.patch
 % qnew implies add
 A .hgignore
 A series
 A uncommitted.patch
 % qnew missing
 abort: missing: No such file or directory
 % qnew -m
 # HG changeset patch
 # Parent 
+
 foo bar
 
 % qnew twice
 abort: patch "first.patch" already exists
 abort: patch "first.patch" already exists
 % qnew -f from a subdirectory
 popping first.patch
 popping mtest.patch
 popping uncommitted.patch
 patch queue now empty
 adding d/b
 M d/b
 # HG changeset patch
 # Parent 
+
 diff --git a/d/b b/d/b
 --- a/d/b
 +++ b/d/b
 @@ -1,1 +1,2 @@
  b
 +b
 % qnew -u with no username configured
 # HG changeset patch
+# User blue
 # Parent 
-# User blue
+
 % fail when trying to import a merge
 adding a
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 created new head
 merging a
 warning: conflicts during merge.
 merging a failed!
 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
 use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
 abort: cannot manage merge changesets
diff --git a/tests/test-mq-qpush-fail b/tests/test-mq-qpush-fail
--- a/tests/test-mq-qpush-fail
+++ b/tests/test-mq-qpush-fail
@@ -1,16 +1,18 @@
 #!/bin/sh
 
 # Test that qpush cleans things up if it doesn't complete
 
 echo "[extensions]" >> $HGRCPATH
 echo "mq=" >> $HGRCPATH
+echo "[mq]" >> $HGRCPATH
+echo "plain=true" >> $HGRCPATH
 
 hg init repo
 cd repo
 
 echo foo > foo
 hg ci -Am 'add foo'
 
 touch untracked-file
 echo 'syntax: glob' > .hgignore
 echo '.hgignore' >> .hgignore
diff --git a/tests/test-mq-qrefresh.out b/tests/test-mq-qrefresh.out
--- a/tests/test-mq-qrefresh.out
+++ b/tests/test-mq-qrefresh.out
@@ -26,20 +26,21 @@
 +patched
 diff -r b55ecdccb5cf 2/base
 --- a/2/base
 +++ b/2/base
 @@ -1,1 +1,1 @@
 -base
 +patched
 % patch file contents
 # HG changeset patch
 # Parent 
+
 mqbase
 
 diff -r b55ecdccb5cf 1/base
 --- a/1/base
 +++ b/1/base
 @@ -1,1 +1,1 @@
 -base
 +patched
 diff -r b55ecdccb5cf 2/base
 --- a/2/base
@@ -70,20 +71,21 @@
 +patched
 diff -r b55ecdccb5cf 2/base
 --- a/2/base
 +++ b/2/base
 @@ -1,1 +1,1 @@
 -base
 +patched
 % patch file contents
 # HG changeset patch
 # Parent 
+
 mqbase
 
 diff -r b55ecdccb5cf 1/base
 --- a/1/base
 +++ b/1/base
 @@ -1,1 +1,1 @@
 -base
 +patched
 % qrefresh . in subdir
 % qdiff
@@ -108,20 +110,21 @@
 +patched
 diff -r b55ecdccb5cf 2/base
 --- a/2/base
 +++ b/2/base
 @@ -1,1 +1,1 @@
 -base
 +patched
 % patch file contents
 # HG changeset patch
 # Parent 
+
 mqbase
 
 diff -r b55ecdccb5cf 1/base
 --- a/1/base
 +++ b/1/base
 @@ -1,1 +1,1 @@
 -base
 +patched
 % qrefresh in hg-root again
 % qdiff
@@ -146,20 +149,21 @@
 +patched
 diff -r b55ecdccb5cf 2/base
 --- a/2/base
 +++ b/2/base
 @@ -1,1 +1,1 @@
 -base
 +patched
 % patch file contents
 # HG changeset patch
 # Parent 
+
 mqbase
 
 diff -r b55ecdccb5cf 1/base
 --- a/1/base
 +++ b/1/base
 @@ -1,1 +1,1 @@
 -base
 +patched
 diff -r b55ecdccb5cf 2/base
 --- a/2/base
@@ -184,20 +188,21 @@
 -base
 +patched
 diff -r b55ecdccb5cf orphanchild
 --- /dev/null
 +++ b/orphanchild
 @@ -0,0 +1,1 @@
 +orphan
 % -- patch file content
 # HG changeset patch
 # Parent 
+
 mqbase
 
 diff -r b55ecdccb5cf 1/base
 --- a/1/base
 +++ b/1/base
 @@ -1,1 +1,1 @@
 -base
 +patched
 diff -r b55ecdccb5cf 2/base
 --- a/2/base
diff --git a/tests/test-mq.out b/tests/test-mq.out
--- a/tests/test-mq.out
+++ b/tests/test-mq.out
@@ -26,20 +26,30 @@
 or deletions. This behaviour can be configured with:
 
   [mq]
   git = auto/keep/yes/no
 
 If set to 'keep', mq will obey the [diff] section configuration while
 preserving existing git patches upon qrefresh. If set to 'yes' or 'no', mq
 will override the [diff] section and always generate git or regular patches,
 possibly losing data in the second case.
 
+By default, mq will automatically use hg-style patch headers when creating new
+patches. This behavior can be changed with:
+
+  [mq]
+  plain = true
+
+If set to 'true', mq will use plain headers with only "Date" and "From"
+fields. For existing patches with headers the header format will always be
+preserved.
+
 list of commands:
 
  qapplied     print the patches already applied
  qclone       clone main and patch repository at same time
  qdelete      remove patches from queue
  qdiff        diff of the current patch and subsequent modifications
  qfinish      move applied patches into repository history
  qfold        fold the named patches into the current patch
  qgoto        push or pop patches until named patch is at top of stack
  qguard       set or print guards for a patch


More information about the Mercurial-devel mailing list