# HG changeset patch # User Roy Marples # Date 1610993078 0 # Node ID a4f13dc5e3f7cbb01d19a83ba35d9420a8d88e13 # Parent a99e5c6c8e1cc60e5150366ef870f4e12184cb05 Support Mercurial 5.6 and Python-3.6 This change the minimum Mercurial supported version 4.1 diff -r a99e5c6c8e1c -r a4f13dc5e3f7 hgfastimport/__init__.py --- 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() diff -r a99e5c6c8e1c -r a4f13dc5e3f7 hgfastimport/hgimport.py --- 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