changeset 74:a4f13dc5e3f7

Support Mercurial 5.6 and Python-3.6 This change the minimum Mercurial supported version 4.1
author Roy Marples <roy@marples.name>
date Mon, 18 Jan 2021 18:04:38 +0000
parents a99e5c6c8e1c
children 59a9e4d0aa72
files hgfastimport/__init__.py hgfastimport/hgimport.py
diffstat 2 files changed, 61 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/hgfastimport/__init__.py	Sun Aug 12 07:54:35 2018 -0400
+++ b/hgfastimport/__init__.py	Mon Jan 18 18:04:38 2021 +0000
@@ -2,9 +2,10 @@
 from __future__ import absolute_import
 
 from mercurial import (
-    cmdutil,
+    commands,
     encoding,
-    util,
+    error,
+    pycompat,
 )
 
 from mercurial.i18n import _
@@ -16,28 +17,30 @@
 
 from .hgimport import fastimport_source
 
+testedwith = b'5.6.1'
+minimumhgversion = b'4.1'
+
 cmdtable = {}
 try:
     from mercurial import registrar
     command = registrar.command(cmdtable)
 except (ImportError, AttributeError):
+    from mercurial import cmdutil
     command = cmdutil.command(cmdtable)
 
-testedwith = '4.7'
-
-@command("fastimport",
-         [('', 'branchsort', None, _('try to sort changesets by branches')),
-          ('', 'datesort', None, _('try to sort changesets by date')),
-          ('', 'sourcesort', None, _('preserve source changesets order'))],
-         _('hg fastimport SOURCE ...'),
-         norepo=False)
+@command(b'fastimport',
+         [(b'', b'branchsort', None, _(b'try to sort changesets by branches')),
+          (b'', b'datesort', None, _(b'try to sort changesets by date')),
+          (b'', b'sourcesort', None, _(b'preserve source changesets order'))],
+         _(b'hg fastimport SOURCE ...'),
+          norepo=False)
 
 def fastimport(ui, repo, *sources, **opts):
-    """Convert a git fastimport dump into Mercurial changesets.
+    '''Convert a git fastimport dump into Mercurial changesets.
 
     Reads a series of SOURCE fastimport dumps and adds the resulting
     changes to the current Mercurial repository.
-    """
+    '''
     # Would be nice to just call hgext.convert.convcmd.convert() and let
     # it take care of things.  But syntax and semantics are just a
     # little mismatched:
@@ -49,24 +52,27 @@
     # Boo, hiss.
 
     if not sources:
-        sources = ("-")
+        sources = (b'-')
 
     # assume fastimport metadata (usernames, commit messages) are
     # encoded UTF-8
     convcmd.orig_encoding = encoding.encoding
-    encoding.encoding = 'UTF-8'
+    encoding.encoding = b'UTF-8'
 
     # sink is the current repo, src is the list of fastimport streams
-    destc = hg.mercurial_sink(ui, 'hg', repo.root)
-    srcc = fastimport_source(ui, 'fastimport', repo, sources)
+    destc = hg.mercurial_sink(ui, b'hg', repo.root)
+    srcc = fastimport_source(ui, b'fastimport', repo, sources)
 
-    # XXX figuring out sortmode copied straight from hgext/convert/convcmd.py
-    defaultsort = 'branchsort'          # for efficiency and consistency
-    sortmodes = ('branchsort', 'datesort', 'sourcesort')
+    opts = pycompat.byteskwargs(opts)
+    defaultsort = b'branchsort'          # for efficiency and consistency
+    sortmodes = (b'branchsort', b'datesort', b'sourcesort')
     sortmode = [m for m in sortmodes if opts.get(m)]
     if len(sortmode) > 1:
-        raise util.Abort(_('more than one sort mode specified'))
-    sortmode = sortmode and sortmode[0] or defaultsort
+        raise error.Abort(_(b'more than one sort mode specified'))
+    if sortmode:
+        sortmode = sortmode[0]
+    else:
+        sortmode = defaultsort
 
     # not implemented: filemap, revmapfile
     revmapfile = destc.revmapfile()
--- a/hgfastimport/hgimport.py	Sun Aug 12 07:54:35 2018 -0400
+++ b/hgfastimport/hgimport.py	Mon Jan 18 18:04:38 2021 +0000
@@ -113,7 +113,7 @@
         if self.parsed:
             return
         for source in self.sources:
-            if source == "-":
+            if source == b"-":
                 infile = sys.stdin
             else:
                 infile = open(source, 'rb')
@@ -128,7 +128,7 @@
 
 class HgImportProcessor(processor.ImportProcessor):
     
-    tagprefix = "refs/tags/"
+    tagprefix = b"refs/tags/"
 
     def __init__(self, ui, repo):
         super(HgImportProcessor, self).__init__()
@@ -155,11 +155,11 @@
     def teardown(self):
         """Cleanup after processing all streams."""
         if self.blobdir and os.path.exists(self.blobdir):
-            self.ui.status("Removing blob dir %r ...\n" % self.blobdir)
+            self.ui.debug(b"Removing blob dir %s ...\n" % self.blobdir)
             shutil.rmtree(self.blobdir)
 
     def progress_handler(self, cmd):
-        self.ui.write("Progress: %s\n" % cmd.message)
+        self.ui.write(b"Progress: %s\n" % cmd.message)
 
     def blob_handler(self, cmd):
         self.writeblob(cmd.id, cmd.data)
@@ -168,7 +168,7 @@
         if self.blobdir is None:
             raise RuntimeError("no blobs seen, so no blob directory created")
         # XXX should escape ":" for windows
-        return os.path.join(self.blobdir, "blob-" + blobid)
+        return os.path.join(self.blobdir, b"blob-" + blobid)
 
     def getblob(self, fileid):
         (commitid, blobid) = fileid
@@ -180,7 +180,7 @@
 
     def writeblob(self, blobid, data):
         if self.blobdir is None:        # no blobs seen yet
-            self.blobdir = os.path.join(self.repo.root, ".hg", "blobs")
+            self.blobdir = os.path.join(self.repo.root, b".hg", b"blobs")
             os.mkdir(self.blobdir)
 
         fn = self._getblobfilename(blobid)
@@ -192,7 +192,7 @@
 
         self.numblobs += 1
         if self.numblobs % 500 == 0:
-            self.ui.status("%d blobs read\n" % self.numblobs)
+            self.ui.status(b"%d blobs read\n" % self.numblobs)
 
     def getmode(self, name, fileid):
         (commitid, blobid) = fileid
@@ -208,7 +208,7 @@
         or a branch with no commits.  Raises KeyError if anything else
         is out of whack.
         """
-        if commitref.startswith(":"):
+        if commitref.startswith(b":"):
             # KeyError here indicates the input stream is broken.
             return self.commitmap[commitref]
         elif commitref.startswith(self.tagprefix):
@@ -216,7 +216,7 @@
         else:
             branch = self._getbranch(commitref)
             if branch is None:
-                raise ValueError("invalid commit ref: %r" % commitref)
+                raise ValueError(b"invalid commit ref: %s" % commitref)
 
             heads = self.branchmap.get(branch)
             if heads is None:
@@ -231,11 +231,11 @@
         Special case: \"refs/heads/master\" becomes \"default\".  If
         'ref' is not a head ref, return None.
         """
-        prefix = "refs/heads/"
+        prefix = b"refs/heads/"
         if ref.startswith(prefix):
             branch = ref[len(prefix):]
-            if branch == "master":
-                return "default"
+            if branch == b"master":
+                return b"default"
             else:
                 return branch
         else:
@@ -247,11 +247,11 @@
         # refs/heads), and implies that it can be called whatever the
         # creator of the fastimport dump wants to call it.  So the name
         # of the fixup branch should be configurable!
-        fixup = (cmd.ref == "refs/heads/TAG.FIXUP")
+        fixup = (cmd.ref == b"refs/heads/TAG.FIXUP")
 
         if cmd.ref.startswith(self.tagprefix) and cmd.mark:
             tag = cmd.ref[len(self.tagprefix):]
-            self.tags.append((tag, ':' + cmd.mark))
+            self.tags.append((tag, b':' + cmd.mark))
 
         if cmd.from_:
             first_parent = cmd.from_
@@ -276,12 +276,14 @@
             second_parent = None
             no_files = True             # XXX this is ignored...
 
-        self.ui.debug("commit %s: first_parent = %r, second_parent = %r\n"
-                      % (cmd, first_parent, second_parent))
+        bfirst_parent = first_parent or b''
+        bsecond_parent = second_parent or b''
+        self.ui.debug(b"commit %s: first_parent = %s, second_parent = %s\n"
+                      % (cmd, bfirst_parent, bsecond_parent))
         assert ((first_parent != second_parent) or
                 (first_parent is second_parent is None)), \
-               ("commit %s: first_parent == second parent = %r"
-                % (cmd, first_parent))
+               (b"commit %s: first_parent == second parent = %s"
+                % (cmd, bfirst_parent))
 
         # Figure out the Mercurial branch name.
         if fixup and first_parent is not None:
@@ -309,12 +311,16 @@
             # we see that, revert to plain old "jsmith".
             user = userinfo[0]
         else:
-            user = "%s <%s>" % (userinfo[0], userinfo[1])
+            user = b"%s <%s>" % (userinfo[0], userinfo[1])
 
         text = cmd.message
         date = self.convert_date(userinfo)
+        parents = []
+        if first_parent:
+            parents.append(first_parent)
+        if second_parent:
+            parents.append(second_parent)
 
-        parents = filter(None, [first_parent, second_parent])
         commit = common.commit(user, date, text, parents, branch,
                                rev=cmd.id, sortkey=int(cmd.id[1:]))
 
@@ -330,7 +336,7 @@
                 pass
             heads.append(cmd.id)        # at end means this is tipmost
         self.branchmap[branch] = heads
-        self.ui.debug("processed commit %s\n" % cmd)
+        self.ui.debug(b"processed commit %s\n" % cmd)
 
     def convert_date(self, c):
         res = (int(c[2]), -int(c[3]))
@@ -339,7 +345,7 @@
         #if type(res) is type((0, 0)) and len(res) == 2:
         #    print "go for it"
         #return res
-        return "%d %d" % res
+        return b"%d %d" % res
         
     def reset_handler(self, cmd):
         branch = self._getbranch(cmd.ref)
@@ -400,7 +406,7 @@
         if filecmd.dataref:
             blobid = filecmd.dataref    # blobid is the mark of the blob
         else:
-            blobid = "%s-inline:%d" % (self.command.id, self.inlinecount)
+            blobid = b"%s-inline:%d" % (self.command.id, self.inlinecount)
             assert filecmd.data is not None
             self.parent.writeblob(blobid, filecmd.data)
             self.inlinecount += 1
@@ -409,13 +415,13 @@
 
         self.modified.append((filecmd.path, fileid))
         if stat.S_ISLNK(filecmd.mode): # link
-            mode = 'l'
-        elif filecmd.mode & 0111: # executable
-            mode = 'x'
+            mode = b'l'
+        elif filecmd.mode & 0o111: # executable
+            mode = b'x'
         elif stat.S_ISREG(filecmd.mode): # regular file
-            mode = ''
+            mode = b''
         else:
-            raise RuntimeError("mode %r unsupported" % filecmd.mode)
+            raise RuntimeError(b"mode %s unsupported" % filecmd.mode)
 
         self.mode[filecmd.path] = mode