##// END OF EJS Templates
tests: coverage of ancestry with convert in multiple non-overlapping steps...
tests: coverage of ancestry with convert in multiple non-overlapping steps This exposes that parent information is lost in cases where it is possible to preserve it - and where it thus would make sense if that was what happened.

File last commit:

r28470:80bd110d default
r28899:8c94594a default
Show More
convcmd.py
608 lines | 21.0 KiB | text/x-python | PythonLexer
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 # convcmd - convert extension commands definition
#
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
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.
timeless
convert: convcmd use absolute_import
r28409 from __future__ import absolute_import
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
timeless
convert: convcmd use absolute_import
r28409 import os
import shlex
import shutil
from mercurial import (
encoding,
error,
hg,
util,
)
from mercurial.i18n import _
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,
)
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
Patrick Mezard
convert: improve cycles detection message
r6131 orig_encoding = 'ascii'
def recode(s):
if isinstance(s, unicode):
return s.encode(orig_encoding, 'replace')
else:
return s.decode('utf-8').encode(orig_encoding, 'replace')
Eugene Baranov
convert: use 'default' for specifying branch name in branchmap (issue4753)...
r25805 def mapbranch(branch, branchmap):
'''
>>> bmap = {'default': 'branch1'}
>>> for i in ['', None]:
... mapbranch(i, bmap)
'branch1'
'branch1'
>>> bmap = {'None': 'branch2'}
>>> for i in ['', None]:
... mapbranch(i, bmap)
'branch2'
'branch2'
>>> bmap = {'None': 'branch3', 'default': 'branch4'}
>>> for i in ['None', '', None, 'default', 'branch5']:
... mapbranch(i, bmap)
'branch3'
'branch4'
'branch4'
'branch4'
'branch5'
'''
# 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.
branch = branchmap.get(branch or 'default', branch)
# At some point we used "None" literal to denote the default branch,
# attempt to use that for backward compatibility.
if (not branch):
branch = branchmap.get(str(None), branch)
return branch
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 source_converters = [
Patrick Mezard
convert: default revisions order depends on source...
r8692 ('cvs', convert_cvs, 'branchsort'),
('git', convert_git, 'branchsort'),
('svn', svn_source, 'branchsort'),
('hg', mercurial_source, 'sourcesort'),
('darcs', darcs_source, 'branchsort'),
('mtn', monotone_source, 'branchsort'),
('gnuarch', gnuarch_source, 'branchsort'),
('bzr', bzr_source, 'branchsort'),
('p4', p4_source, 'branchsort'),
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 ]
sink_converters = [
('hg', mercurial_sink),
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5631 ('svn', svn_sink),
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 ]
Durham Goode
convert: add support for specifying multiple revs...
r25748 def convertsource(ui, path, type, 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]:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('%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:
Durham Goode
convert: add support for specifying multiple revs...
r25748 return source(ui, 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:
Martin Geisler
move % out of translatable strings...
r6913 ui.write("%s\n" % inst)
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('%s: missing or unsupported repository') % path)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
def convertsink(ui, path, type):
Patrick Mezard
convert: better error on invalid repository type
r9962 if type and type not in [s[0] for s in sink_converters]:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('%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:
return sink(ui, path)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except NoRepo as inst:
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 ui.note(_("convert: %s\n") % inst)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except MissingTool as inst:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort('%s\n' % inst)
raise error.Abort(_('%s: unknown repository type') % path)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Patrick Mezard
convert: display files data retrieval progress
r11136 class progresssource(object):
def __init__(self, ui, source, filecount):
self.ui = ui
self.source = source
self.filecount = filecount
self.retrieved = 0
def getfile(self, file, rev):
self.retrieved += 1
timeless
convert/progress: use plural and avoid retrieving
r11731 self.ui.progress(_('getting files'), self.retrieved,
av6
convert: specify unit for ui.progress when operating on files
r28470 item=file, total=self.filecount, unit=_('files'))
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):
timeless
convert/progress: use plural and avoid retrieving
r11731 self.ui.progress(_('getting files'), None)
Patrick Mezard
convert: display files data retrieval progress
r11136
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 class converter(object):
def __init__(self, ui, source, dest, revmapfile, opts):
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
Martin Geisler
convert: deprecate --authors in preference for --authormap...
r12198 if opts.get('authormap'):
self.readauthormap(opts.get('authormap'))
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 self.authorfile = self.dest.authorfile()
Ben Goswami
splicemap: move parsesplicemap to convcmd.py (issue2084)...
r19119 self.splicemap = self.parsesplicemap(opts.get('splicemap'))
Michael J. Pedersen
convert: adding branchmap functionality to convert extension
r8377 self.branchmap = mapfile(ui, opts.get('branchmap'))
Bryan O'Sullivan
convert: allow synthetic history to be spliced in....
r5996
Ben Goswami
splicemap: improve error handling when source is hg (issue2084)...
r19120 def parsesplicemap(self, path):
""" 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: move parsesplicemap to convcmd.py (issue2084)...
r19119
if not path:
return {}
m = {}
try:
fp = open(path, 'r')
for i, line in enumerate(fp):
line = line.splitlines()[0].rstrip()
if not line:
# Ignore blank lines
continue
Szymon Wroblewski
splicemap: support paths with spaces in splicemap (issue3844)...
r19181 # split line
lex = shlex.shlex(line, posix=True)
lex.whitespace_split = True
lex.whitespace += ','
line = list(lex)
# check number of parents
if not (2 <= len(line) <= 3):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('syntax error in %s(%d): child parent1'
Szymon Wroblewski
splicemap: support paths with spaces in splicemap (issue3844)...
r19181 '[,parent2] expected') % (path, i + 1))
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
Ben Goswami
splicemap: improve error handling when source is hg (issue2084)...
r19120 # if file does not exist or error reading, exit
except IOError:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('splicemap file not found or error reading %s:')
Ben Goswami
splicemap: improve error handling when source is hg (issue2084)...
r19120 % path)
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):
'''Return a mapping that identifies the uncommitted parents of every
uncommitted changeset.'''
visit = 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()
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)
Augie Fackler
convert: add support for deterministic progress bar on scanning phase...
r22411 self.ui.progress(_('scanning'), len(known), unit=_('revisions'),
total=numcommits)
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)
Patrick Mezard
convert: add progress support
r11135 self.ui.progress(_('scanning'), None)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
return parents
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 def mergesplicemap(self, parents, splicemap):
"""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
self.ui.warn(_('splice map revision %s is not being '
'converted, ignoring\n') % c)
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:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('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):
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 '''Return an ordering such that every uncommitted changeset is
Mads Kiilerich
fix trivial spelling errors
r17424 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.
"""
Mads Kiilerich
convert: make toposort order stable when multiple orderings are possible...
r18376 visit = 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:
n = visit.pop(0)
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: split toposort() into subfunctions for readability
r8688 # Sort functions are supposed to take a list of revisions which
# can be converted immediately and pick one
Patrick Mezard
convert: fix --datesort ordering...
r6100
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688 def makebranchsorter():
"""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.
"""
prev = [None]
def picknext(nodes):
next = nodes[0]
for n in nodes:
if prev[0] in parents[n]:
next = n
break
prev[0] = next
return next
return picknext
Patrick Mezard
convert: add --sourcesort option for source specific sort...
r8690 def makesourcesorter():
"""Source specific sort."""
keyfn = lambda n: self.commitcache[n].sortkey
def picknext(nodes):
return sorted(nodes, key=keyfn)[0]
return picknext
Constantine Linnick
convert: add closesort algorithm to mercurial sources...
r18819 def makeclosesorter():
"""Close order sort."""
keyfn = lambda n: ('close' not in self.commitcache[n].extra,
self.commitcache[n].sortkey)
def picknext(nodes):
return sorted(nodes, key=keyfn)[0]
return picknext
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688 def makedatesorter():
"""Sort revisions by date."""
Patrick Mezard
convert: fix --datesort ordering...
r6100 dates = {}
def getdate(n):
if n not in dates:
dates[n] = util.parsedate(self.commitcache[n].date)
return dates[n]
def picknext(nodes):
return min([(getdate(n), n) for n in nodes])[1]
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688
return picknext
Patrick Mezard
convert: parse sort mode sooner
r8689 if sortmode == 'branchsort':
picknext = makebranchsorter()
elif sortmode == 'datesort':
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688 picknext = makedatesorter()
Patrick Mezard
convert: add --sourcesort option for source specific sort...
r8690 elif sortmode == 'sourcesort':
picknext = makesourcesorter()
Constantine Linnick
convert: add closesort algorithm to mercurial sources...
r18819 elif sortmode == 'closesort':
picknext = makeclosesorter()
Patrick Mezard
convert: fix --datesort ordering...
r6100 else:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('unknown sort mode: %s') % sortmode)
Patrick Mezard
convert: split toposort() into subfunctions for readability
r8688
children, actives = mapchildren(parents)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
s = []
Patrick Mezard
convert: fix --datesort ordering...
r6100 pendings = {}
while actives:
n = picknext(actives)
actives.remove(n)
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:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cycle detected between %s and %s')
Patrick Mezard
convert: improve cycles detection message
r6131 % (recode(c), recode(n)))
Patrick Mezard
convert: fix --datesort ordering...
r6100 if not pendings[c]:
# Parents are converted, node is eligible
actives.insert(0, c)
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):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("not all revisions were sorted"))
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
return s
def writeauthormap(self):
authorfile = self.authorfile
if authorfile:
Martin Geisler
convert: lowercase status and abort messages
r16925 self.ui.status(_('writing author map file %s\n') % authorfile)
Peter Arrenbrecht
cleanup: whitespace cleanup
r7877 ofile = open(authorfile, 'w+')
for author in self.authors:
ofile.write("%s=%s\n" % (author, self.authors[author]))
ofile.close()
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
def readauthormap(self, authorfile):
afile = open(authorfile, 'r')
for line in afile:
Marti Raudsepp
convert: fix authormap handling of lines without '='...
r7962
Marti Raudsepp
convert: handle comments starting with '#' in authormap files
r7968 line = line.strip()
if not line or line.startswith('#'):
Marti Raudsepp
convert: Ignore empty lines in authormap file.
r6184 continue
Marti Raudsepp
convert: fix authormap handling of lines without '='...
r7962
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 try:
Marti Raudsepp
convert: Clean up authormap key=value splitting....
r6186 srcauthor, dstauthor = line.split('=', 1)
Marti Raudsepp
convert: fix authormap handling of lines without '='...
r7962 except ValueError:
Martin Geisler
convert: lowercase status and abort messages
r16925 msg = _('ignoring bad line in author map file %s: %s\n')
Marti Raudsepp
convert: fix authormap handling of lines without '='...
r7962 self.ui.warn(msg % (authorfile, line.rstrip()))
continue
srcauthor = srcauthor.strip()
dstauthor = dstauthor.strip()
if self.authors.get(srcauthor) in (None, dstauthor):
msg = _('mapping author %s to %s\n')
self.ui.debug(msg % (srcauthor, dstauthor))
self.authors[srcauthor] = dstauthor
continue
m = _('overriding mapping for author %s, was %s, will be %s\n')
self.ui.status(m % (srcauthor, self.authors[srcauthor], dstauthor))
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 afile.close()
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
def copy(self, rev):
commit = self.commitcache[rev]
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 full = self.opts.get('full')
changes = self.source.getchanges(rev, full)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 if isinstance(changes, basestring):
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)
Thomas Arendsen Hein
Removed trailing spaces from everything except test output
r6210 pbranches.append((self.map[prev],
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 self.commitcache[prev].branch))
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]
Martin Geisler
i18n: mark strings for translation in convert extension
r6956 self.ui.status(_('spliced in %s as parents of %s\n') %
Mads Kiilerich
convert: fix Python syntax in 'splice in' message...
r26812 (_(' and ').join(parents), rev))
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]
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.
source = progresssource(self.ui, self.source,
len(files) * (len(parents) - 1))
Dirkjan Ochtman
kill trailing whitespace
r8843 newnode = self.dest.putcommit(files, copies, parents, commit,
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 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
Patrick Mezard
convert: parse sort mode sooner
r8689 def convert(self, sortmode):
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)
Martin Geisler
i18n: mark strings for translation in convert extension
r6956 self.ui.status(_("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)
Martin Geisler
i18n: mark strings for translation in convert extension
r6956 self.ui.status(_("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
Martin Geisler
i18n: mark strings for translation in convert extension
r6956 self.ui.status(_("converting...\n"))
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
if "\n" in desc:
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'
Patrick Mezard
convert: display source revision id with --verbose
r5954 self.ui.status("%d %s\n" % (num, recode(desc)))
Martin Geisler
move % out of translatable strings...
r6913 self.ui.note(_("source: %s\n") % recode(c))
Patrick Mezard
convert: add progress support
r11135 self.ui.progress(_('converting'), i, unit=_('revisions'),
total=len(t))
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 self.copy(c)
Patrick Mezard
convert: add progress support
r11135 self.ui.progress(_('converting'), None)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
Durham Goode
convert: add config to not convert tags...
r25741 if not self.ui.configbool('convert', 'skiptags'):
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
tagsparents = [e for e in self.map.iteritems()
if e[1] == tagsparent]
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()
def cleanup(self):
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
def convert(ui, src, dest=None, revmapfile=None, **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
encoding.encoding = '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
if not opts.get('authormap'):
opts['authormap'] = opts.get('authors')
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 if not dest:
dest = hg.defaultdest(src) + "-hg"
Martin Geisler
i18n: mark strings for translation in convert extension
r6956 ui.status(_("assuming destination %s\n") % dest)
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621
destc = convertsink(ui, dest, opts.get('dest_type'))
try:
Patrick Mezard
convert: default revisions order depends on source...
r8692 srcc, defaultsort = convertsource(ui, src, opts.get('source_type'),
opts.get('rev'))
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
Constantine Linnick
convert: add closesort algorithm to mercurial sources...
r18819 sortmodes = ('branchsort', 'datesort', 'sourcesort', '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:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('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
Patrick Mezard
convert: fail fast if source does not support --sourcesort
r8691 if sortmode == 'sourcesort' and not srcc.hasnativeorder():
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('--sourcesort is not supported by this data source')
)
Constantine Linnick
convert: add closesort algorithm to mercurial sources...
r18819 if sortmode == 'closesort' and not srcc.hasnativeclose():
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('--closesort is not supported by this data source'))
Patrick Mezard
convert: parse sort mode sooner
r8689
Patrick Mezard
convert: move commands definition to ease demandload job (issue 860)
r5621 fmap = opts.get('filemap')
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)