##// END OF EJS Templates
check-code: detect legacy octal syntax...
check-code: detect legacy octal syntax Now that we have mass rewriting all files to use the modern octal syntax, detect and ban the legacy syntax, which is no longer supported in Python 3.

File last commit:

r25589:273d9425 default
r25659:d60678a5 default
Show More
hg.py
561 lines | 20.1 KiB | text/x-python | PythonLexer
Martin Geisler
convert: add copyright and license headers to back-ends
r8250 # hg.py - hg backend for convert extension
#
# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
#
# 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.
Brendan Cully
Split convert extension into common and repository type modules
r4536
Bryan O'Sullivan
convert: some tidyups, doc improvements, and test fixes...
r5556 # Notes for hg->hg conversion:
#
# * Old versions of Mercurial didn't trim the whitespace from the ends
# of commit messages, but new versions do. Changesets created by
# those older versions, then converted, may thus have different
# hashes for changesets that are otherwise identical.
#
Patrick Mezard
convert/hg: update documentation
r8596 # * Using "--config convert.hg.saverev=true" will make the source
# identifier to be stored in the converted revision. This will cause
# the converted revision to have a different identity than the
# source.
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013
Patrick Mezard
convert: rewrite tags when converting from hg to hg
r8693 import os, time, cStringIO
Bryan O'Sullivan
convert: acquire/release locks periodically
r5014 from mercurial.i18n import _
Joel Rosdahl
Expand import * to allow Pyflakes to find problems
r6211 from mercurial.node import bin, hex, nullid
Pierre-Yves David
convert-hg: use localrepo.pull...
r22698 from mercurial import hg, util, context, bookmarks, error, scmutil, exchange
Matt Harbison
convert: apply the appropriate phases to the destination (issue4165)...
r25571 from mercurial import phases
Brendan Cully
Split convert extension into common and repository type modules
r4536
Matt Harbison
convert: support incremental conversion with hg subrepos...
r25558 from common import NoRepo, commit, converter_source, converter_sink, mapfile
Brendan Cully
Split convert extension into common and repository type modules
r4536
Sean Farley
convert: replace old sha1s in the description...
r20372 import re
Mads Kiilerich
convert: replace revision references in messages if they are >= short hashes...
r23972 sha1re = re.compile(r'\b[0-9a-f]{12,40}\b')
Sean Farley
convert: replace old sha1s in the description...
r20372
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 class mercurial_sink(converter_sink):
Brendan Cully
convert: split converter into convertsource and convertsink
r4763 def __init__(self, ui, path):
Bryan O'Sullivan
convert: add default constructor for converter_sink
r5440 converter_sink.__init__(self, ui, path)
Brendan Cully
convert: hg: optionally create branches as clones...
r5173 self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
Brendan Cully
convert: new config variable hg.tagsbranch controls which branch tags are committed to
r5260 self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
Brendan Cully
convert: hg: optionally create branches as clones...
r5173 self.lastbranch = None
Bryan O'Sullivan
convert: refactor sink initialisation, to remove hardcoding of hg...
r5441 if os.path.isdir(path) and len(os.listdir(path)) > 0:
try:
self.repo = hg.repository(self.ui, path)
Patrick Mezard
convert: mercurial sink must be local
r5918 if not self.repo.local():
Martin Geisler
convert: write "repository" instead of "repo"...
r10938 raise NoRepo(_('%s is not a local Mercurial repository')
% path)
Matt Mackall
error: move repo errors...
r7637 except error.RepoError, err:
Matt Mackall
ui: print_exc() -> traceback()
r8206 ui.traceback()
Bryan O'Sullivan
convert: refactor sink initialisation, to remove hardcoding of hg...
r5441 raise NoRepo(err.args[0])
else:
try:
ui.status(_('initializing destination %s repository\n') % path)
self.repo = hg.repository(self.ui, path, create=True)
Patrick Mezard
convert: mercurial sink must be local
r5918 if not self.repo.local():
Martin Geisler
convert: write "repository" instead of "repo"...
r10938 raise NoRepo(_('%s is not a local Mercurial repository')
% path)
Bryan O'Sullivan
convert: refactor sink initialisation, to remove hardcoding of hg...
r5441 self.created.append(path)
Peter Arrenbrecht
cleanup: drop unused assignments
r7875 except error.RepoError:
Matt Mackall
ui: print_exc() -> traceback()
r8206 ui.traceback()
Martin Geisler
convert: mark strings for translation
r10939 raise NoRepo(_("could not create hg repository %s as sink")
Martin Geisler
convert: write "repository" instead of "repo"...
r10938 % path)
Bryan O'Sullivan
convert: acquire/release locks periodically
r5014 self.lock = None
self.wlock = None
Alexis S. L. Carvalho
convert: add a mode where mercurial_sink skips empty revisions....
r5378 self.filemapmode = False
Matt Harbison
convert: support incremental conversion with hg subrepos...
r25558 self.subrevmaps = {}
Bryan O'Sullivan
convert: acquire/release locks periodically
r5014
def before(self):
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('run hg sink pre-conversion action\n')
Alexis S. L. Carvalho
convert: fix locking order
r5052 self.wlock = self.repo.wlock()
Bryan O'Sullivan
convert: acquire/release locks periodically
r5014 self.lock = self.repo.lock()
def after(self):
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('run hg sink post-conversion action\n')
Matt Mackall
convert: make hg sink cleanup safer
r10086 if self.lock:
self.lock.release()
if self.wlock:
self.wlock.release()
Brendan Cully
Split convert extension into common and repository type modules
r4536
Bryan O'Sullivan
convert: rename mapfile to revmapfile, so we can map more than just revs
r5011 def revmapfile(self):
Martin Geisler
convert: use repo.join instead of referencing ".hg" directly
r15069 return self.repo.join("shamap")
Brendan Cully
Split convert extension into common and repository type modules
r4536
Edouard Gomez
convert extension: Add support for username mapping...
r4589 def authorfile(self):
Martin Geisler
convert: use repo.join instead of referencing ".hg" directly
r15069 return self.repo.join("authormap")
Edouard Gomez
convert extension: Add support for username mapping...
r4589
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 def setbranch(self, branch, pbranches):
if not self.clonebranches:
Brendan Cully
convert: hg: optionally create branches as clones...
r5173 return
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 setbranch = (branch != self.lastbranch)
Brendan Cully
convert: hg: optionally create branches as clones...
r5173 self.lastbranch = branch
if not branch:
branch = 'default'
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 pbranches = [(b[0], b[1] and b[1] or 'default') for b in pbranches]
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if pbranches:
pbranch = pbranches[0][1]
else:
pbranch = 'default'
Brendan Cully
convert: hg: optionally create branches as clones...
r5173
branchpath = os.path.join(self.path, branch)
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 if setbranch:
self.after()
try:
self.repo = hg.repository(self.ui, branchpath)
Brodie Rao
cleanup: replace naked excepts with except Exception: ...
r16689 except Exception:
Brendan Cully
convert: hg: optionally create branches as clones...
r5173 self.repo = hg.repository(self.ui, branchpath, create=True)
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 self.before()
# pbranches may bring revisions from other branches (merge parents)
# Make sure we have them, or pull them.
missings = {}
for b in pbranches:
try:
self.repo.lookup(b[0])
Brodie Rao
cleanup: replace naked excepts with except Exception: ...
r16689 except Exception:
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 missings.setdefault(b[1], []).append(b[0])
Thomas Arendsen Hein
Removed trailing spaces from everything except test output
r6210
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 if missings:
self.after()
Mads Kiilerich
convert: process missing branches in sorted order
r18373 for pbranch, heads in sorted(missings.iteritems()):
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 pbranchpath = os.path.join(self.path, pbranch)
Matt Mackall
hg: change various repository() users to use peer() where appropriate...
r14556 prepo = hg.peer(self.ui, {}, pbranchpath)
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 self.ui.note(_('pulling from %s into %s\n') % (pbranch, branch))
Pierre-Yves David
convert-hg: use localrepo.pull...
r22698 exchange.pull(self.repo, prepo,
[prepo.lookup(h) for h in heads])
Patrick Mezard
convert: hg.clonebranches must pull missing parents (issue941)
r5934 self.before()
Brendan Cully
convert: hg: optionally create branches as clones...
r5173
Mads Kiilerich
convert: backout b75a04502ced and 9616b03113ce - tagmap...
r21076 def _rewritetags(self, source, revmap, data):
Patrick Mezard
convert: rewrite tags when converting from hg to hg
r8693 fp = cStringIO.StringIO()
for line in data.splitlines():
s = line.split(' ', 1)
if len(s) != 2:
continue
revid = revmap.get(source.lookuprev(s[0]))
if not revid:
Matt Mackall
convert: properly pass null ids through .hgtags (issue4678)...
r25305 if s[0] == hex(nullid):
revid = s[0]
else:
continue
Mads Kiilerich
convert: backout b75a04502ced and 9616b03113ce - tagmap...
r21076 fp.write('%s %s\n' % (revid, s[1]))
Patrick Mezard
convert: rewrite tags when converting from hg to hg
r8693 return fp.getvalue()
Matt Harbison
convert: support incremental conversion with hg subrepos...
r25558 def _rewritesubstate(self, source, data):
fp = cStringIO.StringIO()
for line in data.splitlines():
s = line.split(' ', 1)
if len(s) != 2:
continue
revid = s[0]
subpath = s[1]
if revid != hex(nullid):
revmap = self.subrevmaps.get(subpath)
if revmap is None:
revmap = mapfile(self.ui,
self.repo.wjoin(subpath, '.hg/shamap'))
self.subrevmaps[subpath] = revmap
# It is reasonable that one or more of the subrepos don't
# need to be converted, in which case they can be cloned
# into place instead of converted. Therefore, only warn
# once.
msg = _('no ".hgsubstate" updates will be made for "%s"\n')
if len(revmap) == 0:
sub = self.repo.wvfs.reljoin(subpath, '.hg')
if self.repo.wvfs.exists(sub):
self.ui.warn(msg % subpath)
newid = revmap.get(revid)
if not newid:
if len(revmap) > 0:
self.ui.warn(_("%s is missing from %s/.hg/shamap\n") %
(revid, subpath))
else:
revid = newid
fp.write('%s %s\n' % (revid, subpath))
return fp.getvalue()
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 def putcommit(self, files, copies, parents, commit, source, revmap, full,
cleanp2):
Patrick Mezard
convert: hg sink commits without working dir
r6717 files = dict(files)
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395
Patrick Mezard
convert: hg sink commits without working dir
r6717 def getfilectx(repo, memctx, f):
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 if p2ctx and f in cleanp2 and f not in copies:
self.ui.debug('reusing %s from p2\n' % f)
return p2ctx[f]
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 try:
v = files[f]
except KeyError:
return None
Patrick Mezard
convert: merge sources getmode() into getfile()
r11134 data, mode = source.getfile(f, v)
Mads Kiilerich
convert: use None value for missing files instead of overloading IOError...
r22296 if data is None:
return None
Patrick Mezard
convert: rewrite tags when converting from hg to hg
r8693 if f == '.hgtags':
Mads Kiilerich
convert: backout b75a04502ced and 9616b03113ce - tagmap...
r21076 data = self._rewritetags(source, revmap, data)
Matt Harbison
convert: support incremental conversion with hg subrepos...
r25558 if f == '.hgsubstate':
data = self._rewritesubstate(source, data)
Sean Farley
memfilectx: call super.__init__ instead of duplicating code...
r21689 return context.memfilectx(self.repo, f, data, 'l' in mode,
'x' in mode, copies.get(f))
Patrick Mezard
convert: hg sink commits without working dir
r6717
Brendan Cully
Split convert extension into common and repository type modules
r4536 pl = []
for p in parents:
Patrick Mezard
convert: hg sink commits without working dir
r6717 if p not in pl:
Brendan Cully
Split convert extension into common and repository type modules
r4536 pl.append(p)
parents = pl
Alexis S. L. Carvalho
convert: add a mode where mercurial_sink skips empty revisions....
r5378 nparents = len(parents)
if self.filemapmode and nparents == 1:
m1node = self.repo.changelog.read(bin(parents[0]))[0]
parent = parents[0]
Brendan Cully
Split convert extension into common and repository type modules
r4536
Matt Mackall
many, many trivial check-code fixups
r10282 if len(parents) < 2:
parents.append(nullid)
if len(parents) < 2:
parents.append(nullid)
Brendan Cully
Split convert extension into common and repository type modules
r4536 p2 = parents.pop(0)
text = commit.desc
Sean Farley
convert: replace old sha1s in the description...
r20372
sha1s = re.findall(sha1re, text)
for sha1 in sha1s:
oldrev = source.lookuprev(sha1)
newrev = revmap.get(oldrev)
if newrev is not None:
text = text.replace(sha1, newrev[:len(sha1)])
Bryan O'Sullivan
convert: make contents of "extra" dict available from sources, for sinks....
r5439 extra = commit.extra.copy()
Matt Harbison
convert: update the transplant, rebase and graft references in 'extra'...
r21765
Matt Harbison
convert: update 'intermediate-source' in the destination's extras dictionary
r25589 for label in ('source', 'transplant_source', 'rebase_source',
'intermediate-source'):
Matt Harbison
convert: update the transplant, rebase and graft references in 'extra'...
r21765 node = extra.get(label)
if node is None:
continue
# Only transplant stores its reference in binary
if label == 'transplant_source':
node = hex(node)
newrev = revmap.get(node)
if newrev is not None:
if label == 'transplant_source':
newrev = bin(newrev)
extra[label] = newrev
Bryan O'Sullivan
convert: add config option to turn off use of branch names
r5038 if self.branchnames and commit.branch:
Brendan Cully
convert: record the source revision in the changelog
r4873 extra['branch'] = commit.branch
Matt Harbison
convert: always track the hg source revision in the internal commit object...
r25570 if commit.rev and commit.saverev:
Brendan Cully
convert: record the source revision in the changelog
r4873 extra['convert_revision'] = commit.rev
Thomas Arendsen Hein
removed trailing whitespace
r4957
Brendan Cully
Split convert extension into common and repository type modules
r4536 while parents:
p1 = p2
p2 = parents.pop(0)
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 p2ctx = None
if p2 != nullid:
p2ctx = self.repo[p2]
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 fileset = set(files)
if full:
Mads Kiilerich
convert: don't use multi-argument set.update...
r22360 fileset.update(self.repo[p1])
fileset.update(self.repo[p2])
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 ctx = context.memctx(self.repo, (p1, p2), text, fileset,
Matt Mackall
many, many trivial check-code fixups
r10282 getfilectx, commit.author, commit.date, extra)
Matt Harbison
convert: apply the appropriate phases to the destination (issue4165)...
r25571
# We won't know if the conversion changes the node until after the
# commit, so copy the source's phase for now.
self.repo.ui.setconfig('phases', 'new-commit',
phases.phasenames[commit.phase], 'convert')
tr = self.repo.transaction("convert")
try:
node = hex(self.repo.commitctx(ctx))
# If the node value has changed, but the phase is lower than
# draft, set it back to draft since it hasn't been exposed
# anywhere.
if commit.rev != node:
ctx = self.repo[node]
if ctx.phase() < phases.draft:
phases.retractboundary(self.repo, tr, phases.draft,
[ctx.node()])
tr.close()
finally:
tr.release()
Brendan Cully
Split convert extension into common and repository type modules
r4536 text = "(octopus merge fixup)\n"
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 p2 = hex(self.repo.changelog.tip())
Brendan Cully
Split convert extension into common and repository type modules
r4536
Alexis S. L. Carvalho
convert: add a mode where mercurial_sink skips empty revisions....
r5378 if self.filemapmode and nparents == 1:
man = self.repo.manifest
mnode = self.repo.changelog.read(bin(p2))[0]
Matt Mackall
convert: handle closed branch heads in hg-hg conversion (issue2185)
r11673 closed = 'close' in commit.extra
if not closed and not man.cmp(m1node, man.revision(mnode)):
Patrick Mezard
convert: better feedback when filtering out empty revisions...
r8611 self.ui.status(_("filtering out empty revision\n"))
Matt Mackall
convert: fix crazy rollback call, broken by recent rollback safety checks...
r15193 self.repo.rollback(force=True)
Alexis S. L. Carvalho
convert: add a mode where mercurial_sink skips empty revisions....
r5378 return parent
Brendan Cully
Split convert extension into common and repository type modules
r4536 return p2
def puttags(self, tags):
Peter Arrenbrecht
cleanup: whitespace cleanup
r7877 try:
parentctx = self.repo[self.tagsbranch]
tagparent = parentctx.node()
except error.RepoError:
parentctx = None
tagparent = nullid
Brendan Cully
Split convert extension into common and repository type modules
r4536
Sean Farley
convert: compare tags from all heads instead of just one...
r20376 oldlines = set()
for branch, heads in self.repo.branchmap().iteritems():
for h in heads:
if '.hgtags' in self.repo[h]:
oldlines.update(
set(self.repo[h]['.hgtags'].data().splitlines(True)))
oldlines = sorted(list(oldlines))
Brendan Cully
Split convert extension into common and repository type modules
r4536
Matt Mackall
replace util.sort with sorted built-in...
r8209 newlines = sorted([("%s %s\n" % (tags[tag], tag)) for tag in tags])
Peter Arrenbrecht
cleanup: whitespace cleanup
r7877 if newlines == oldlines:
Patrick Mezard
convert: fix history topology when using hg.tagsbranch...
r9431 return None, None
Sean Farley
convert: avoid updating tags when there is nothing new...
r20377
# if the old and new tags match, then there is nothing to update
oldtags = set()
newtags = set()
for line in oldlines:
s = line.strip().split(' ', 1)
if len(s) != 2:
continue
oldtags.add(s[1])
for line in newlines:
s = line.strip().split(' ', 1)
if len(s) != 2:
continue
if s[1] not in oldtags:
newtags.add(s[1].strip())
if not newtags:
return None, None
Peter Arrenbrecht
cleanup: whitespace cleanup
r7877 data = "".join(newlines)
def getfilectx(repo, memctx, f):
Sean Farley
memfilectx: call super.__init__ instead of duplicating code...
r21689 return context.memfilectx(repo, f, data, False, False, None)
Patrick Mezard
convert: hg sink commits without working dir
r6717
Peter Arrenbrecht
cleanup: whitespace cleanup
r7877 self.ui.status(_("updating tags\n"))
date = "%s 0" % int(time.mktime(time.gmtime()))
extra = {'branch': self.tagsbranch}
ctx = context.memctx(self.repo, (tagparent, None), "update tags",
[".hgtags"], getfilectx, "convert-repo", date,
extra)
self.repo.commitctx(ctx)
Patrick Mezard
convert: fix history topology when using hg.tagsbranch...
r9431 return hex(self.repo.changelog.tip()), hex(tagparent)
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013
Alexis S. L. Carvalho
convert: add a mode where mercurial_sink skips empty revisions....
r5378 def setfilemapmode(self, active):
self.filemapmode = active
Edouard Gomez
convert: add bookmark support to the hg sink
r13746 def putbookmarks(self, updatedbookmark):
if not len(updatedbookmark):
return
self.ui.status(_("updating bookmarks\n"))
Augie Fackler
bookmarks: introduce a bmstore to manage bookmark persistence...
r17922 destmarks = self.repo._bookmarks
Edouard Gomez
convert: add bookmark support to the hg sink
r13746 for bookmark in updatedbookmark:
Augie Fackler
bookmarks: introduce a bmstore to manage bookmark persistence...
r17922 destmarks[bookmark] = bin(updatedbookmark[bookmark])
destmarks.write()
Edouard Gomez
convert: add bookmark support to the hg sink
r13746
Mads Kiilerich
convert: introduce hascommitfrommap sink method...
r21635 def hascommitfrommap(self, rev):
# the exact semantics of clonebranches is unclear so we can't say no
return rev in self.repo or self.clonebranches
Mads Kiilerich
convert: rename sink hascommit to hascommitforsplicemap...
r21634 def hascommitforsplicemap(self, rev):
Brodie Rao
cleanup: "not x in y" -> "x not in y"
r16686 if rev not in self.repo and self.clonebranches:
Wagner Bruna
convert: fix typos in error messages
r16162 raise util.Abort(_('revision %s not found in destination '
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 'repository (lookups with clonebranches=true '
'are not implemented)') % rev)
return rev in self.repo
Edouard Gomez
convert: add bookmark support to the hg sink
r13746
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 class mercurial_source(converter_source):
def __init__(self, ui, path, rev=None):
converter_source.__init__(self, ui, path, rev)
Patrick Mezard
convert: ignore hg source errors with hg.ignoreerrors (issue 1357)...
r7231 self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
Benoit Boissinot
convert: use set instead of dict
r8456 self.ignored = set()
Matt Mackall
convert: change hg.saverev default to False...
r7815 self.saverev = ui.configbool('convert', 'hg.saverev', False)
Bryan O'Sullivan
convert: fail properly if we can't read a source hg repository
r5358 try:
self.repo = hg.repository(self.ui, path)
Bryan O'Sullivan
convert: report errors more meaningfully if run with --traceback
r5437 # try to provoke an exception if this isn't really a hg
# repo, but some other bogus compatible-looking url
Alexis S. L. Carvalho
convert: make sure mercurial_source has a local hg repo
r5522 if not self.repo.local():
Brodie Rao
cleanup: "raise SomeException()" -> "raise SomeException"
r16687 raise error.RepoError
Matt Mackall
error: move repo errors...
r7637 except error.RepoError:
Matt Mackall
ui: print_exc() -> traceback()
r8206 ui.traceback()
Martin Geisler
convert: mark strings for translation
r10939 raise NoRepo(_("%s is not a local Mercurial repository") % path)
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 self.lastrev = None
self.lastctx = None
Mads Kiilerich
convert: refactor hg getchanges and caching
r22299 self._changescache = None, None
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554 self.convertfp = None
Patrick Mezard
convert: implement startrev for hg source
r6885 # Restrict converted revisions to startrev descendants
startnode = ui.config('convert', 'hg.startrev')
Mads Kiilerich
convert: introduce hg.revs to replace hg.startrev and --rev with a revset...
r19891 hgrevs = ui.config('convert', 'hg.revs')
if hgrevs is None:
if startnode is not None:
try:
startnode = self.repo.lookup(startnode)
except error.RepoError:
raise util.Abort(_('%s is not a valid start revision')
% startnode)
startrev = self.repo.changelog.rev(startnode)
children = {startnode: 1}
for r in self.repo.changelog.descendants([startrev]):
children[self.repo.changelog.node(r)] = 1
self.keep = children.__contains__
else:
self.keep = util.always
if rev:
self._heads = [self.repo[rev].node()]
else:
self._heads = self.repo.heads()
Patrick Mezard
convert: implement startrev for hg source
r6885 else:
Mads Kiilerich
convert: introduce hg.revs to replace hg.startrev and --rev with a revset...
r19891 if rev or startnode is not None:
raise util.Abort(_('hg.revs cannot be combined with '
'hg.startrev or --rev'))
nodes = set()
parents = set()
for r in scmutil.revrange(self.repo, [hgrevs]):
ctx = self.repo[r]
nodes.add(ctx.node())
parents.update(p.node() for p in ctx.parents())
self.keep = nodes.__contains__
self._heads = nodes - parents
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013
def changectx(self, rev):
if self.lastrev != rev:
Matt Mackall
use repo[changeid] to get a changectx
r6747 self.lastctx = self.repo[rev]
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 self.lastrev = rev
return self.lastctx
Patrick Mezard
convert: implement startrev for hg source
r6885 def parents(self, ctx):
Patrick Mezard
convert/hg: make parents() return changectx, not nodes
r9531 return [p for p in ctx.parents() if p and self.keep(p.node())]
Patrick Mezard
convert: implement startrev for hg source
r6885
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 def getheads(self):
Mads Kiilerich
convert: refactor head calculation for hg sources
r19890 return [hex(h) for h in self._heads if self.keep(h)]
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013
def getfile(self, name, rev):
try:
Patrick Mezard
convert: merge sources getmode() into getfile()
r11134 fctx = self.changectx(rev)[name]
return fctx.data(), fctx.flags()
Mads Kiilerich
convert: use None value for missing files instead of overloading IOError...
r22296 except error.LookupError:
return None, None
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 def getchanges(self, rev, full):
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 ctx = self.changectx(rev)
Patrick Mezard
convert: implement startrev for hg source
r6885 parents = self.parents(ctx)
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 if full or not parents:
Mads Kiilerich
convert: refactor hg getchanges and caching
r22299 files = copyfiles = ctx.manifest()
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 if parents:
Mads Kiilerich
convert: refactor hg getchanges and caching
r22299 if self._changescache[0] == rev:
m, a, r = self._changescache[1]
else:
m, a, r = self.repo.status(parents[0].node(), ctx.node())[:3]
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 if not full:
files = m + a + r
Mads Kiilerich
convert: refactor hg getchanges and caching
r22299 copyfiles = m + a
# getcopies() is also run for roots and before filtering so missing
# revlogs are detected early
copies = self.getcopies(ctx, parents, copyfiles)
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 cleanp2 = set()
if len(parents) == 2:
cleanp2.update(self.repo.status(parents[1].node(), ctx.node(),
clean=True).clean)
Mads Kiilerich
convert: refactor hg getchanges and caching
r22299 changes = [(f, rev) for f in files if f not in self.ignored]
changes.sort()
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 return changes, copies, cleanp2
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013
Patrick Mezard
convert/hg: handle bogus copy records (issue1843)
r9532 def getcopies(self, ctx, parents, files):
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 copies = {}
Alexis S. L. Carvalho
convert: mercurial_source: also search for copies in modified files...
r5280 for name in files:
Patrick Mezard
convert: ignore hg source errors with hg.ignoreerrors (issue 1357)...
r7231 if name in self.ignored:
continue
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 try:
Mads Kiilerich
convert: fix bad conversion of copies when hg.startrev is specified...
r19457 copysource, _copynode = ctx.filectx(name).renamed()
if copysource in self.ignored:
Patrick Mezard
convert: ignore hg source errors with hg.ignoreerrors (issue 1357)...
r7231 continue
Patrick Mezard
convert/hg: handle bogus copy records (issue1843)
r9532 # Ignore copy sources not in parent revisions
found = False
for p in parents:
if copysource in p:
found = True
break
if not found:
continue
Patrick Mezard
convert: ignore hg source errors with hg.ignoreerrors (issue 1357)...
r7231 copies[name] = copysource
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 except TypeError:
pass
Matt Mackall
errors: move revlog errors...
r7633 except error.LookupError, e:
Patrick Mezard
convert: ignore hg source errors with hg.ignoreerrors (issue 1357)...
r7231 if not self.ignoreerrors:
raise
Benoit Boissinot
convert: use set instead of dict
r8456 self.ignored.add(name)
Patrick Mezard
convert: ignore hg source errors with hg.ignoreerrors (issue 1357)...
r7231 self.ui.warn(_('ignoring: %s\n') % e)
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 return copies
Thomas Arendsen Hein
Remove trailing spaces, fix indentation
r5143
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013 def getcommit(self, rev):
ctx = self.changectx(rev)
Patrick Mezard
convert/hg: make parents() return changectx, not nodes
r9531 parents = [p.hex() for p in self.parents(ctx)]
Matt Harbison
convert: always track the hg source revision in the internal commit object...
r25570 crev = rev
FUJIWARA Katsunori
i18n: use locale insensitive format for datetimes as intermediate representation (issue3398)...
r16514 return commit(author=ctx.user(),
date=util.datestr(ctx.date(), '%Y-%m-%d %H:%M:%S %1%2'),
Bryan O'Sullivan
convert: some tidyups, doc improvements, and test fixes...
r5556 desc=ctx.description(), rev=crev, parents=parents,
Patrick Mezard
convert: add --sourcesort option for source specific sort...
r8690 branch=ctx.branch(), extra=ctx.extra(),
Matt Harbison
convert: apply the appropriate phases to the destination (issue4165)...
r25571 sortkey=ctx.rev(), saverev=self.saverev,
phase=ctx.phase())
Bryan O'Sullivan
convert: Support Mercurial as a source, as well as a sink
r5013
def gettags(self):
Mads Kiilerich
convert: mercurial source: convert global tags only - not local tags...
r21498 # This will get written to .hgtags, filter non global tags out.
tags = [t for t in self.repo.tagslist()
if self.repo.tagtype(t[0]) == 'global']
Patrick Mezard
convert: implement startrev for hg source
r6885 return dict([(name, hex(node)) for name, node in tags
if self.keep(node)])
Alexis S. L. Carvalho
mercurial_source: add --filemap support
r5379
def getchangedfiles(self, rev, i):
ctx = self.changectx(rev)
Patrick Mezard
convert: implement startrev for hg source
r6885 parents = self.parents(ctx)
if not parents and i is None:
i = 0
changes = [], ctx.manifest().keys(), []
else:
i = i or 0
Patrick Mezard
convert/hg: make parents() return changectx, not nodes
r9531 changes = self.repo.status(parents[i].node(), ctx.node())[:3]
Patrick Mezard
convert: ignore hg source errors with hg.ignoreerrors (issue 1357)...
r7231 changes = [[f for f in l if f not in self.ignored] for l in changes]
Alexis S. L. Carvalho
mercurial_source: add --filemap support
r5379
if i == 0:
self._changescache = (rev, changes)
return changes[0] + changes[1] + changes[2]
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554 def converted(self, rev, destrev):
if self.convertfp is None:
Martin Geisler
convert: use repo.join instead of referencing ".hg" directly
r15069 self.convertfp = open(self.repo.join('shamap'), 'a')
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554 self.convertfp.write('%s %s\n' % (destrev, rev))
self.convertfp.flush()
Patrick Mezard
test-convert: test before() and after() conversion actions
r5805
def before(self):
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('run hg source pre-conversion action\n')
Patrick Mezard
test-convert: test before() and after() conversion actions
r5805
def after(self):
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('run hg source post-conversion action\n')
Patrick Mezard
convert: fail fast if source does not support --sourcesort
r8691
def hasnativeorder(self):
return True
Patrick Mezard
convert: rewrite tags when converting from hg to hg
r8693
Constantine Linnick
convert: add closesort algorithm to mercurial sources...
r18819 def hasnativeclose(self):
return True
Patrick Mezard
convert: rewrite tags when converting from hg to hg
r8693 def lookuprev(self, rev):
try:
return hex(self.repo.lookup(rev))
Matt Harbison
convert: handle LookupError in mercurial_source.lookuprev()...
r23926 except (error.RepoError, error.LookupError):
Patrick Mezard
convert: rewrite tags when converting from hg to hg
r8693 return None
Edouard Gomez
convert: add bookmark support to hg source
r13757
def getbookmarks(self):
return bookmarks.listbookmarks(self.repo)
Ben Goswami
splicemap: improve error handling when source is hg (issue2084)...
r19120
Sean Farley
convert: add mapname parameter to checkrevformat...
r20373 def checkrevformat(self, revstr, mapname='splicemap'):
Ben Goswami
splicemap: improve error handling when source is hg (issue2084)...
r19120 """ Mercurial, revision string is a 40 byte hex """
Sean Farley
convert: add mapname parameter to checkrevformat...
r20373 self.checkhexformat(revstr, mapname)