Commits

rcohen committed 64f7e42

Get rid of readheaders() in favor of patch.extract() and always using HG changeset patches.

Comments (0)

Files changed (1)

 from mercurial.i18n import _
 from mercurial import commands, cmdutil, hg, patch, util
 from mercurial import extensions, fancyopts
-import cStringIO, os, re, errno, tempfile
+from mercurial.node import hex, bin
+import cStringIO, os, re, errno, tempfile, sys
 
 normname = util.normpath
 
             self.persiststate()
         return success
 
-    def readheaders(self, patch):
-        """reads the headers of a patch; copied from mq"""
-        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
-
-        pf = self.join(patch)
-        message = []
-        comments = []
-        user = date = format = subject = None
-        diffstart = 0
-        gitdiff = False
-
-        for line in file(pf):
-            line = line.rstrip()
-            if line.startswith('diff --git'):
-                diffstart = 2
-                gitdiff=True
-                break
-            if diffstart:
-                if line.startswith('+++ '):
-                    diffstart = 2
-                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 not line.startswith('# ') and line:
-                    message.append(line)
-                    format = None
-            elif line == '# HG changeset patch':
-                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 == '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)
-
-        eatdiff(message)
-        eatdiff(comments)
-        eatempty(message)
-        eatempty(comments)
-
-        # make sure message isn't empty
-        if format and format.startswith('tag') and subject:
-            message.insert(0, '')
-            message.insert(0, subject)
-        return (message, comments, user, date, diffstart > 1, gitdiff)
-
     def createpatch(self, repo, name, msg, user, date, pats=[], opts={}):
         """creates a patch from the current state of the working copy"""
-        p = self.opener(name, 'w')
+        fp = self.opener(name, 'w')
+        ctx = repo[None]
+        fp.write('# HG changeset patch\n')
+        if user:
+            fp.write('# User %s\n' % user)
         if date:
-            p.write('# HG changeset patch\n')
-            if user:
-                p.write('# User ' + user + '\n')
-            p.write('# Date %d %d\n' % date)
-            p.write('\n')
-        elif user:
-            p.write('From: ' + user + '\n')
-            p.write('\n')
+            fp.write('# Date %d %d\n' % date)
+        parents = [p.node() for p in ctx.parents() if p]
+        fp.write('# Parent  %s\n' % hex(parents[0]))
         if msg:
             if not isinstance(msg, str):
                 msg = '\n'.join(msg)
-            msg = msg + '\n'
-            p.write(msg)
+            if msg and msg[-1] != '\n':
+                msg += '\n'
+            fp.write(msg)
         m = cmdutil.match(repo, pats, opts)
         chunks = patch.diff(repo, match = m, opts = self.diffopts(opts))
         for chunk in chunks:
-            p.write(chunk)
-        p.close()
+            fp.write(chunk)
+        fp.close()
         self.currentpatch=name
         self.persiststate()
 
     do('user', ui.username())
     do('date', '%d %d' % util.makedate())
 
-def makepatch(ui, repo, name=None, pats=None, opts=None):
+def makepatch(ui, repo, name=None, pats=[], opts={}):
     """sets up the call for attic.createpatch and makes the call"""
-    if pats == None:
-        pats = []
-    if opts == None:
-        opts = {}
-
     s = repo.attic
-    usr = msg = ''
-    d = date = user = None
     force = opts.get('force')
-
     if name and s.exists(name) and name != s.applied and not force:
         raise util.Abort(_('attempting to overwrite existing patch'))
     if name and s.applied and name != s.applied and not force:
         name = s.applied
     if not name:
         raise util.Abort(_('you need to supply a patch name'))
-    message = cmdutil.logmessage(opts)
+
+    date, user, message = None, None, ''
+    if s.applied:
+        data = patch.extract(ui, open(s.join(s.applied), 'r'))
+        tmpname, message, user, date, branch, nodeid, p1, p2 = data
+        os.unlink(tmpname)
+    msg = cmdutil.logmessage(opts)
+    if not msg:
+        msg = message
     if opts.get('edit'):
-        message = ui.edit(message, ui.username())
+        msg = ui.edit(msg, ui.username())
     setupheaderopts(ui, opts)
     if opts.get('user'):
-        usr=opts['user']
+        user=opts['user']
+    if not user:
+        user = ui.username()
     if opts.get('date'):
-        d=opts['date']
-    if s.applied:
-        (msg, comments, user, date, hasdiff, gitdiff) = s.readheaders(s.applied)
-        if gitdiff:
-            opts['git'] = 1
-    if message:
-        msg = message
-    if usr:
-        user = usr
-    if d:
-        date = d
-    if date:
-        date = util.parsedate(date)
+        date=opts['date']
+    if not date:
+        date = util.makedate()
+    date = util.parsedate(date)
     s.createpatch(repo, name, msg, user, date, pats, opts)
 
 def headerinfo(ui, repo, name):
-    s = repo.attic
-    (message, comments, user, date, hasdiff, g) = s.readheaders(name)
+    name = repo.attic.join(name)
+    data = patch.extract(ui, open(name, 'r'))
+    tmpname, message, user, date, branch, nodeid, p1, p2 = data
+    os.unlink(tmpname)
     if not isinstance(message, str):
         message = '\n'.join(message)
-    if not message:
-        message = None
+    if not message or message.strip() == '':
+        message = 'None\n'
     else:
         message = '\n' + message
-    ui.write(_('user: %s\ndate: %s\nmessage: %s\n') %
-                  (user, date, message))
+    ui.write(_('user: %s\ndate: %s\nparent: %s\nmessage: %s') %
+                  (user, date, p1, message))
 
 def currentinfo(ui, repo):
     """lists the current active patch"""
         orig(ui, repo, *args, **opts)
     else:
         makepatch(ui, repo, name, [], opts)
-        (m, comments, u, d, hasdiff, gitdiff) = s.readheaders(name)
-        orig(ui, repo, message = '\n'.join(m),
-             logfile = None, user = u, date = d)
+        data = patch.extract(ui, open(s.join(name), 'r'))
+        tmpname, m, u, d, branch, nodeid, p1, p2 = data
+        os.unlink(tmpname)
+        orig(ui, repo, message = m, logfile = None, user = u, date = d)
 
         if not opts.get('keep'):
             s.remove(name)