##// END OF EJS Templates
monotone: replace %s interpolation with appropriate numeric specifiers...
monotone: replace %s interpolation with appropriate numeric specifiers The length is an int, and the version is a float. Neither work with bytes on py3. This was noticed when looking at nearby code after updating pytype changed some signatures.

File last commit:

r52596:ca7bde5d default
r52707:f1ef512e default
Show More
convcmd.py
710 lines | 23.0 KiB | text/x-python | PythonLexer
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 # convcmd - convert extension commands definition
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Gregory Szorc
convert: use a collections.deque...
r35797 import collections
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 import heapq
timeless
convert: convcmd use absolute_import
r28409 import os
import shutil
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 import typing
from typing import (
AnyStr,
Matt Harbison
convert: fix various leaked file descriptors...
r52580 Dict,
List,
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 Mapping,
Optional,
Union,
)
timeless
convert: convcmd use absolute_import
r28409
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205 from mercurial.i18n import _
Gregory Szorc
py3: manually import pycompat.open into files that need it...
r43355 from mercurial.pycompat import open
timeless
convert: convcmd use absolute_import
r28409 from mercurial import (
encoding,
error,
hg,
Augie Fackler
convcmd: pass encoding name as a sysstr...
r36150 pycompat,
Matt Harbison
convert: allow the sink object to be wrapped when the extension isn't loaded...
r35169 scmutil,
timeless
convert: convcmd use absolute_import
r28409 util,
)
Boris Feld
util: extract all date-related utils in utils/dateutil module...
r36625 from mercurial.utils import dateutil
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
timeless
convert: convcmd use absolute_import
r28409 from . import (
bzr,
common,
cvs,
darcs,
filemap,
git,
gnuarch,
hg as hgconvert,
monotone,
p4,
subversion,
)
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 if typing.TYPE_CHECKING:
from mercurial import (
ui as uimod,
)
timeless
convert: convcmd use absolute_import
r28409 mapfile = common.mapfile
MissingTool = common.MissingTool
NoRepo = common.NoRepo
SKIPREV = common.SKIPREV
bzr_source = bzr.bzr_source
convert_cvs = cvs.convert_cvs
convert_git = git.convert_git
darcs_source = darcs.darcs_source
gnuarch_source = gnuarch.gnuarch_source
mercurial_sink = hgconvert.mercurial_sink
mercurial_source = hgconvert.mercurial_source
monotone_source = monotone.monotone_source
p4_source = p4.p4_source
svn_sink = subversion.svn_sink
svn_source = subversion.svn_source
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 orig_encoding: bytes = b'ascii'
Patrick Mezard
convert: improve cycles detection message
r6131
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def readauthormap(ui: "uimod.ui", authorfile, authors=None):
Joerg Sonnenberger
convert: refactor authormap into separate function for outside use...
r44561 if authors is None:
authors = {}
with open(authorfile, b'rb') as afile:
for line in afile:
line = line.strip()
if not line or line.startswith(b'#'):
continue
try:
srcauthor, dstauthor = line.split(b'=', 1)
except ValueError:
msg = _(b'ignoring bad line in author map file %s: %s\n')
ui.warn(msg % (authorfile, line.rstrip()))
continue
srcauthor = srcauthor.strip()
dstauthor = dstauthor.strip()
if authors.get(srcauthor) in (None, dstauthor):
msg = _(b'mapping author %s to %s\n')
ui.debug(msg % (srcauthor, dstauthor))
authors[srcauthor] = dstauthor
continue
m = _(b'overriding mapping for author %s, was %s, will be %s\n')
ui.status(m % (srcauthor, authors[srcauthor], dstauthor))
return authors
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def recode(s: AnyStr) -> bytes:
Gregory Szorc
py3: use str instead of pycompat.unicode...
r49789 if isinstance(s, str):
Augie Fackler
convcmd: pass encoding name as a sysstr...
r36150 return s.encode(pycompat.sysstr(orig_encoding), 'replace')
Patrick Mezard
convert: improve cycles detection message
r6131 else:
Augie Fackler
convcmd: pass encoding name as a sysstr...
r36150 return s.decode('utf-8').encode(
Augie Fackler
formatting: blacken the codebase...
r43346 pycompat.sysstr(orig_encoding), 'replace'
)
Patrick Mezard
convert: improve cycles detection message
r6131
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def mapbranch(branch: bytes, branchmap: Mapping[bytes, bytes]) -> bytes:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> bmap = {b'default': b'branch1'}
>>> for i in [b'', None]:
Eugene Baranov
convert: use 'default' for specifying branch name in branchmap (issue4753)...
r25805 ... mapbranch(i, bmap)
'branch1'
'branch1'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> bmap = {b'None': b'branch2'}
>>> for i in [b'', None]:
Eugene Baranov
convert: use 'default' for specifying branch name in branchmap (issue4753)...
r25805 ... mapbranch(i, bmap)
'branch2'
'branch2'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> bmap = {b'None': b'branch3', b'default': b'branch4'}
>>> for i in [b'None', b'', None, b'default', b'branch5']:
Eugene Baranov
convert: use 'default' for specifying branch name in branchmap (issue4753)...
r25805 ... mapbranch(i, bmap)
'branch3'
'branch4'
'branch4'
'branch4'
'branch5'
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Eugene Baranov
convert: use 'default' for specifying branch name in branchmap (issue4753)...
r25805 # If branch is None or empty, this commit is coming from the source
# repository's default branch and destined for the default branch in the
# destination repository. For such commits, using a literal "default"
# in branchmap below allows the user to map "default" to an alternate
# default branch in the destination repository.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 branch = branchmap.get(branch or b'default', branch)
Eugene Baranov
convert: use 'default' for specifying branch name in branchmap (issue4753)...
r25805 # At some point we used "None" literal to denote the default branch,
# attempt to use that for backward compatibility.
Augie Fackler
formatting: blacken the codebase...
r43346 if not branch:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 branch = branchmap.get(b'None', branch)
Eugene Baranov
convert: use 'default' for specifying branch name in branchmap (issue4753)...
r25805 return branch
Augie Fackler
formatting: blacken the codebase...
r43346
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 source_converters = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'cvs', convert_cvs, b'branchsort'),
(b'git', convert_git, b'branchsort'),
(b'svn', svn_source, b'branchsort'),
(b'hg', mercurial_source, b'sourcesort'),
(b'darcs', darcs_source, b'branchsort'),
(b'mtn', monotone_source, b'branchsort'),
(b'gnuarch', gnuarch_source, b'branchsort'),
(b'bzr', bzr_source, b'branchsort'),
(b'p4', p4_source, b'branchsort'),
Augie Fackler
formatting: blacken the codebase...
r43346 ]
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
sink_converters = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'hg', mercurial_sink),
(b'svn', svn_sink),
Augie Fackler
formatting: blacken the codebase...
r43346 ]
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def convertsource(ui: "uimod.ui", path: bytes, type: bytes, revs):
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 exceptions = []
Patrick Mezard
convert: better error on invalid repository type
r9962 if type and type not in [s[0] for s in source_converters]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'%s: invalid source repository type') % type)
Patrick Mezard
convert: default revisions order depends on source...
r8692 for name, source, sortmode in source_converters:
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 try:
if not type or name == type:
Matt Harbison
convert: save an indicator of the repo type for sources and sinks...
r35168 return source(ui, name, path, revs), sortmode
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except (NoRepo, MissingTool) as inst:
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 exceptions.append(inst)
if not ui.quiet:
for inst in exceptions:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(b"%s\n" % pycompat.bytestr(inst.args[0]))
raise error.Abort(_(b'%s: missing or unsupported repository') % path)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def convertsink(
ui: "uimod.ui", path: bytes, type: bytes
) -> Union[hgconvert.mercurial_sink, subversion.svn_sink]:
Patrick Mezard
convert: better error on invalid repository type
r9962 if type and type not in [s[0] for s in sink_converters]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'%s: invalid destination repository type') % type)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 for name, sink in sink_converters:
try:
if not type or name == type:
Matt Harbison
convert: save an indicator of the repo type for sources and sinks...
r35168 return sink(ui, name, path)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except NoRepo as inst:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.note(_(b"convert: %s\n") % inst)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except MissingTool as inst:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(b'%s\n' % inst)
raise error.Abort(_(b'%s: unknown repository type') % path)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class progresssource:
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def __init__(
self, ui: "uimod.ui", source, filecount: Optional[int]
) -> None:
Patrick Mezard
convert: display files data retrieval progress
r11136 self.ui = ui
self.source = source
Augie Fackler
formatting: blacken the codebase...
r43346 self.progress = ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'getting files'), unit=_(b'files'), total=filecount
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
convert: display files data retrieval progress
r11136
def getfile(self, file, rev):
Martin von Zweigbergk
convert: use progress helper...
r38425 self.progress.increment(item=file)
Patrick Mezard
convert: display files data retrieval progress
r11136 return self.source.getfile(file, rev)
Durham Goode
convert: add function to test if file is from source...
r26035 def targetfilebelongstosource(self, targetfilename):
return self.source.targetfilebelongstosource(targetfilename)
Patrick Mezard
convert: display files data retrieval progress
r11136 def lookuprev(self, rev):
return self.source.lookuprev(rev)
def close(self):
Martin von Zweigbergk
convert: use progress helper...
r38425 self.progress.complete()
Patrick Mezard
convert: display files data retrieval progress
r11136
Augie Fackler
formatting: blacken the codebase...
r43346
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 # Sorters are used by the `toposort` function to maintain a set of revisions
# which can be converted immediately and pick one
class branchsorter:
"""If the previously converted revision has a child in the
eligible revisions list, pick it. Return the list head
otherwise. Branch sort attempts to minimize branch
switching, which is harmful for Mercurial backend
compression.
"""
def __init__(self, parents):
self.nodes = []
self.parents = parents
self.prev = None
def picknext(self):
next = self.nodes[0]
for n in self.nodes:
if self.prev in self.parents[n]:
next = n
break
self.prev = next
self.nodes.remove(next)
return next
def insert(self, node):
self.nodes.insert(0, node)
def __len__(self):
return self.nodes.__len__()
class keysorter:
"""Key-based sort, ties broken by insertion order"""
def __init__(self, keyfn):
self.heap = []
self.keyfn = keyfn
self.counter = 0
def picknext(self):
return heapq.heappop(self.heap)[2]
def insert(self, node):
counter = self.counter
self.counter = counter + 1
key = self.keyfn(node)
heapq.heappush(self.heap, (key, counter, node))
def __len__(self):
return self.heap.__len__()
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class converter:
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def __init__(self, ui: "uimod.ui", source, dest, revmapfile, opts) -> None:
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 self.source = source
self.dest = dest
self.ui = ui
self.opts = opts
self.commitcache = {}
self.authors = {}
self.authorfile = None
Greg Ward
convert: improve docstrings, comments.
r8444 # Record converted revisions persistently: maps source revision
Dirkjan Ochtman
kill trailing whitespace
r8843 # ID to target revision ID (both strings). (This is how
Greg Ward
convert: improve docstrings, comments.
r8444 # incremental conversions work.)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5631 self.map = mapfile(ui, revmapfile)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
# Read first the dst author map if any
authorfile = self.dest.authorfile()
if authorfile and os.path.exists(authorfile):
self.readauthormap(authorfile)
# Extend/Override with new author map if necessary
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'authormap'):
self.readauthormap(opts.get(b'authormap'))
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 self.authorfile = self.dest.authorfile()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.splicemap = self.parsesplicemap(opts.get(b'splicemap'))
self.branchmap = mapfile(ui, opts.get(b'branchmap'))
Bryan O'Sullivan
convert: allow synthetic history to be spliced in....
r5996
Matt Harbison
convert: fix various leaked file descriptors...
r52580 def parsesplicemap(self, path: bytes) -> Dict[bytes, List[bytes]]:
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """check and validate the splicemap format and
return a child/parents dictionary.
Format checking has two parts.
1. generic format which is same across all source types
2. specific format checking which may be different for
different source type. This logic is implemented in
checkrevformat function in source files like
hg.py, subversion.py etc.
Ben Goswami
splicemap: improve error handling when source is hg (issue2084)...
r19120 """
Ben Goswami
splicemap: move parsesplicemap to convcmd.py (issue2084)...
r19119
if not path:
return {}
m = {}
try:
Matt Harbison
convert: fix various leaked file descriptors...
r52580 with open(path, b'rb') as fp:
for i, line in enumerate(fp):
line = line.splitlines()[0].rstrip()
if not line:
# Ignore blank lines
continue
# split line
lex = common.shlexer(data=line, whitespace=b',')
line = list(lex)
# check number of parents
if not (2 <= len(line) <= 3):
raise error.Abort(
_(
b'syntax error in %s(%d): child parent1'
b'[,parent2] expected'
)
% (path, i + 1)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
convert: fix various leaked file descriptors...
r52580 for part in line:
self.source.checkrevformat(part)
child, p1, p2 = line[0], line[1:2], line[2:]
if p1 == p2:
m[child] = p1
else:
m[child] = p1 + p2
Augie Fackler
formatting: blacken the codebase...
r43346 # if file does not exist or error reading, exit
Ben Goswami
splicemap: improve error handling when source is hg (issue2084)...
r19120 except IOError:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'splicemap file not found or error reading %s:') % path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Ben Goswami
splicemap: move parsesplicemap to convcmd.py (issue2084)...
r19119 return m
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 def walktree(self, heads):
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Return a mapping that identifies the uncommitted parents of every
uncommitted changeset."""
Augie Fackler
convcmd: make a copy of heads before mutating it...
r37905 visit = list(heads)
Benoit Boissinot
convert: use set instead of dict
r8456 known = set()
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 parents = {}
Augie Fackler
convert: add support for deterministic progress bar on scanning phase...
r22411 numcommits = self.source.numcommits()
Augie Fackler
formatting: blacken the codebase...
r43346 progress = self.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'scanning'), unit=_(b'revisions'), total=numcommits
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 while visit:
n = visit.pop(0)
Mads Kiilerich
convert: only consider shamap revisions converted if they still exists...
r21636 if n in known:
Matt Mackall
many, many trivial check-code fixups
r10282 continue
Mads Kiilerich
convert: only consider shamap revisions converted if they still exists...
r21636 if n in self.map:
m = self.map[n]
if m == SKIPREV or self.dest.hascommitfrommap(m):
continue
Benoit Boissinot
convert: use set instead of dict
r8456 known.add(n)
Martin von Zweigbergk
convert: use progress helper...
r38425 progress.update(len(known))
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 commit = self.cachecommit(n)
parents[n] = []
for p in commit.parents:
parents[n].append(p)
visit.append(p)
Martin von Zweigbergk
convert: use progress helper...
r38425 progress.complete()
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
return parents
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def mergesplicemap(self, parents, splicemap) -> None:
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 """A splicemap redefines child/parent relationships. Check the
map contains valid revision identifiers and merge the new
links in the source graph.
"""
Mads Kiilerich
convert: process splicemap in sorted order
r18372 for c in sorted(splicemap):
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 if c not in parents:
Mads Kiilerich
convert: rename sink hascommit to hascommitforsplicemap...
r21634 if not self.dest.hascommitforsplicemap(self.map.get(c, c)):
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 # Could be in source but not converted during this run
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'splice map revision %s is not being '
b'converted, ignoring\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% c
)
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 continue
pc = []
for p in splicemap[c]:
# We do not have to wait for nodes already in dest.
Mads Kiilerich
convert: rename sink hascommit to hascommitforsplicemap...
r21634 if self.dest.hascommitforsplicemap(self.map.get(p, p)):
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 continue
# Parent is not in dest and not being converted, not good
if p not in parents:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'unknown splice map parent: %s') % p)
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 pc.append(p)
parents[c] = pc
Patrick Mezard
convert: parse sort mode sooner
r8689 def toposort(self, parents, sortmode):
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Return an ordering such that every uncommitted changeset is
preceded by all its uncommitted ancestors."""
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688
def mapchildren(parents):
"""Return a (children, roots) tuple where 'children' maps parent
revision identifiers to children ones, and 'roots' is the list of
revisions without parents. 'parents' must be a mapping of revision
identifier to its parents ones.
"""
Gregory Szorc
convert: use a collections.deque...
r35797 visit = collections.deque(sorted(parents))
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688 seen = set()
children = {}
roots = []
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688 while visit:
Gregory Szorc
convert: use a collections.deque...
r35797 n = visit.popleft()
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688 if n in seen:
continue
seen.add(n)
# Ensure that nodes without parents are present in the
# 'children' mapping.
children.setdefault(n, [])
hasparent = False
for p in parents[n]:
Brodie Rao
cleanup: "not x in y" -> "x not in y"
r16686 if p not in self.map:
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688 visit.append(p)
hasparent = True
children.setdefault(p, []).append(n)
if not hasparent:
roots.append(n)
return children, roots
Patrick Mezard
convert: fix --datesort ordering...
r6100
Patrick Mezard
convert: add --sourcesort option for source specific sort...
r8690 def makesourcesorter():
"""Source specific sort."""
keyfn = lambda n: self.commitcache[n].sortkey
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 return keysorter(keyfn)
Patrick Mezard
convert: add --sourcesort option for source specific sort...
r8690
Constantine Linnick
convert: add closesort algorithm to mercurial sources...
r18819 def makeclosesorter():
"""Close order sort."""
Augie Fackler
formatting: blacken the codebase...
r43346 keyfn = lambda n: (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'close' not in self.commitcache[n].extra,
Augie Fackler
formatting: blacken the codebase...
r43346 self.commitcache[n].sortkey,
)
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 return keysorter(keyfn)
Constantine Linnick
convert: add closesort algorithm to mercurial sources...
r18819
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688 def makedatesorter():
"""Sort revisions by date."""
Augie Fackler
formatting: blacken the codebase...
r43346
Patrick Mezard
convert: fix --datesort ordering...
r6100 def getdate(n):
convert: stabilize subversion date sorter...
r51780 commit = self.commitcache[n]
# The other entries are here as tie breaker for stability
return (
dateutil.parsedate(commit.date),
commit.rev,
commit.branch,
)
Patrick Mezard
convert: fix --datesort ordering...
r6100
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 return keysorter(getdate)
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if sortmode == b'branchsort':
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 sorter = branchsorter(parents)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif sortmode == b'datesort':
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 sorter = makedatesorter()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif sortmode == b'sourcesort':
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 sorter = makesourcesorter()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif sortmode == b'closesort':
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 sorter = makeclosesorter()
Patrick Mezard
convert: fix --datesort ordering...
r6100 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'unknown sort mode: %s') % sortmode)
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 children, roots = mapchildren(parents)
for node in roots:
sorter.insert(node)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
s = []
Patrick Mezard
convert: fix --datesort ordering...
r6100 pendings = {}
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 while sorter:
n = sorter.picknext()
Patrick Mezard
convert: fix --datesort ordering...
r6100 s.append(n)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Patrick Mezard
convert: fix --datesort ordering...
r6100 # Update dependents list
for c in children.get(n, []):
if c not in pendings:
pendings[c] = [p for p in parents[c] if p not in self.map]
Patrick Mezard
convert: improve cycles detection message
r6131 try:
pendings[c].remove(n)
except ValueError:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'cycle detected between %s and %s')
Augie Fackler
formatting: blacken the codebase...
r43346 % (recode(c), recode(n))
)
Patrick Mezard
convert: fix --datesort ordering...
r6100 if not pendings[c]:
# Parents are converted, node is eligible
Arseniy Alekseyev
convert: use a priority queue for sorting commits, to make sorting faster...
r51076 sorter.insert(c)
Patrick Mezard
convert: fix --datesort ordering...
r6100 pendings[c] = None
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Patrick Mezard
convert: fix --datesort ordering...
r6100 if len(s) != len(parents):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"not all revisions were sorted"))
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
return s
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def writeauthormap(self) -> None:
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 authorfile = self.authorfile
if authorfile:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(_(b'writing author map file %s\n') % authorfile)
Matt Harbison
convert: fix various leaked file descriptors...
r52580 with open(authorfile, b'wb+') as ofile:
for author in self.authors:
ofile.write(
util.tonativeeol(
b"%s=%s\n" % (author, self.authors[author])
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 )
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def readauthormap(self, authorfile) -> None:
Joerg Sonnenberger
convert: refactor authormap into separate function for outside use...
r44561 self.authors = readauthormap(self.ui, authorfile, self.authors)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
def cachecommit(self, rev):
commit = self.source.getcommit(rev)
commit.author = self.authors.get(commit.author, commit.author)
Eugene Baranov
convert: use 'default' for specifying branch name in branchmap (issue4753)...
r25805 commit.branch = mapbranch(commit.branch, self.branchmap)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 self.commitcache[rev] = commit
return commit
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def copy(self, rev) -> None:
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 commit = self.commitcache[rev]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 full = self.opts.get(b'full')
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 changes = self.source.getchanges(rev, full)
Pulkit Goyal
py3: use bytes in place of basestring...
r35198 if isinstance(changes, bytes):
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 if changes == SKIPREV:
dest = SKIPREV
else:
dest = self.map[changes]
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5631 self.map[rev] = dest
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 return
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 files, copies, cleanp2 = changes
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 pbranches = []
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 if commit.parents:
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 for prev in commit.parents:
if prev not in self.commitcache:
self.cachecommit(prev)
Augie Fackler
formatting: blacken the codebase...
r43346 pbranches.append(
(self.map[prev], self.commitcache[prev].branch)
)
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 self.dest.setbranch(commit.branch, pbranches)
Bryan O'Sullivan
convert: allow synthetic history to be spliced in....
r5996 try:
Patrick Mezard
convert: turn splicemap into a simple dictionary...
r16105 parents = self.splicemap[rev]
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'spliced in %s as parents of %s\n')
% (_(b' and ').join(parents), rev)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Bryan O'Sullivan
convert: document splicemap, allow setting of multiple parents
r6143 parents = [self.map.get(p, p) for p in parents]
Bryan O'Sullivan
convert: allow synthetic history to be spliced in....
r5996 except KeyError:
parents = [b[0] for b in pbranches]
Augie Fackler
formatting: blacken the codebase...
r43346 parents.extend(
self.map[x] for x in commit.optparents if x in self.map
)
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 if len(pbranches) != 2:
cleanp2 = set()
Augie Fackler
convert: adjust progress bar for octopus merges (issue4169)...
r24328 if len(parents) < 3:
source = progresssource(self.ui, self.source, len(files))
else:
# For an octopus merge, we end up traversing the list of
# changed files N-1 times. This tweak to the number of
# files makes it so the progress bar doesn't overflow
# itself.
Augie Fackler
formatting: blacken the codebase...
r43346 source = progresssource(
self.ui, self.source, len(files) * (len(parents) - 1)
)
newnode = self.dest.putcommit(
files, copies, parents, commit, source, self.map, full, cleanp2
)
Patrick Mezard
convert: display files data retrieval progress
r11136 source.close()
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5631 self.source.converted(rev, newnode)
self.map[rev] = newnode
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def convert(self, sortmode) -> None:
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 try:
self.source.before()
self.dest.before()
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5631 self.source.setrevmap(self.map)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(_(b"scanning source...\n"))
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 heads = self.source.getheads()
parents = self.walktree(heads)
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 self.mergesplicemap(parents, self.splicemap)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(_(b"sorting...\n"))
Patrick Mezard
convert: parse sort mode sooner
r8689 t = self.toposort(parents, sortmode)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 num = len(t)
c = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(_(b"converting...\n"))
Augie Fackler
formatting: blacken the codebase...
r43346 progress = self.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'converting'), unit=_(b'revisions'), total=len(t)
Augie Fackler
formatting: blacken the codebase...
r43346 )
timeless
convert: kill trailing whitespace
r12769 for i, c in enumerate(t):
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 num -= 1
desc = self.commitcache[c].desc
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b"\n" in desc:
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 desc = desc.splitlines()[0]
Shun-ichi GOTO
convert: print commit log message with local encoding correctly.
r5794 # convert log message to local encoding without using
timeless
convert: fix typo in comment
r12768 # tolocal() because the encoding.encoding convert()
# uses is 'utf-8'
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.status(b"%d %s\n" % (num, recode(desc)))
self.ui.note(_(b"source: %s\n") % recode(c))
Martin von Zweigbergk
convert: use progress helper...
r38425 progress.update(i)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 self.copy(c)
Martin von Zweigbergk
convert: use progress helper...
r38425 progress.complete()
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not self.ui.configbool(b'convert', b'skiptags'):
Durham Goode
convert: add config to not convert tags...
r25741 tags = self.source.gettags()
ctags = {}
for k in tags:
v = tags[k]
if self.map.get(v, SKIPREV) != SKIPREV:
ctags[k] = self.map[v]
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Durham Goode
convert: add config to not convert tags...
r25741 if c and ctags:
nrev, tagsparent = self.dest.puttags(ctags)
if nrev and tagsparent:
# write another hash correspondence to override the
# previous one so we don't end up with extra tag heads
Augie Fackler
formatting: blacken the codebase...
r43346 tagsparents = [
Gregory Szorc
global: bulk replace simple pycompat.iteritems(x) with x.items()...
r49768 e for e in self.map.items() if e[1] == tagsparent
Augie Fackler
formatting: blacken the codebase...
r43346 ]
Durham Goode
convert: add config to not convert tags...
r25741 if tagsparents:
self.map[tagsparents[0][0]] = nrev
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Edouard Gomez
convert: add bookmark support to main command...
r13745 bookmarks = self.source.getbookmarks()
cbookmarks = {}
for k in bookmarks:
v = bookmarks[k]
if self.map.get(v, SKIPREV) != SKIPREV:
cbookmarks[k] = self.map[v]
if c and cbookmarks:
self.dest.putbookmarks(cbookmarks)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 self.writeauthormap()
finally:
self.cleanup()
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def cleanup(self) -> None:
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 try:
self.dest.after()
finally:
self.source.after()
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5631 self.map.close()
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
typing: add trivial type hints to the convert extension's common modules...
r52578 def convert(
ui: "uimod.ui", src, dest: Optional[bytes] = None, revmapfile=None, **opts
) -> None:
Pulkit Goyal
py3: use pycompat.byteskwargs in hgext/convert/...
r36347 opts = pycompat.byteskwargs(opts)
Shun-ichi GOTO
convert: print commit log message with local encoding correctly.
r5794 global orig_encoding
Matt Mackall
move encoding bits from util to encoding...
r7948 orig_encoding = encoding.encoding
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 encoding.encoding = b'UTF-8'
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Martin Geisler
convert: deprecate --authors in preference for --authormap...
r12198 # support --authors as an alias for --authormap
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'authormap'):
opts[b'authormap'] = opts.get(b'authors')
Martin Geisler
convert: deprecate --authors in preference for --authormap...
r12198
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 if not dest:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 dest = hg.defaultdest(src) + b"-hg"
ui.status(_(b"assuming destination %s\n") % dest)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 destc = convertsink(ui, dest, opts.get(b'dest_type'))
Matt Harbison
convert: allow the sink object to be wrapped when the extension isn't loaded...
r35169 destc = scmutil.wrapconvertsink(destc)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
try:
Augie Fackler
formatting: blacken the codebase...
r43346 srcc, defaultsort = convertsource(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui, src, opts.get(b'source_type'), opts.get(b'rev')
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 except Exception:
for path in destc.created:
shutil.rmtree(path, True)
raise
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 sortmodes = (b'branchsort', b'datesort', b'sourcesort', b'closesort')
Patrick Mezard
convert: add --sourcesort option for source specific sort...
r8690 sortmode = [m for m in sortmodes if opts.get(m)]
if len(sortmode) > 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'more than one sort mode specified'))
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if sortmode:
sortmode = sortmode[0]
else:
sortmode = defaultsort
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if sortmode == b'sourcesort' and not srcc.hasnativeorder():
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'--sourcesort is not supported by this data source')
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if sortmode == b'closesort' and not srcc.hasnativeclose():
raise error.Abort(
_(b'--closesort is not supported by this data source')
)
Patrick Mezard
convert: parse sort mode sooner
r8689
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fmap = opts.get(b'filemap')
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 if fmap:
srcc = filemap.filemap_source(ui, srcc, fmap)
destc.setfilemapmode(True)
if not revmapfile:
Mads Kiilerich
convert: remove unused and incorrect default handling for revmapfile...
r19889 revmapfile = destc.revmapfile()
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
c = converter(ui, srcc, destc, revmapfile, opts)
Patrick Mezard
convert: parse sort mode sooner
r8689 c.convert(sortmode)