##// END OF EJS Templates
revset: make tokenize extensible to parse alias declarations and definitions...
revset: make tokenize extensible to parse alias declarations and definitions Before this patch, "tokenize" doesn't recognize the symbol starting with "$" as a valid one. This prevents revset alias declarations and definitions from being parsed with "tokenize", because "$" may be used as the initial letter of alias arguments. BTW, the alias argument name doesn't require leading "$" itself, in fact. But we have to assume that users may use "$" as the initial letter of argument names in their aliases, because examples in "hg help revsets" uses such names for a long time. To make "tokenize" extensible to parse alias declarations and definitions, this patch introduces optional arguments "syminitletters" and "symletters". Giving these sets can change the policy of "valid symbol" in tokenization easily. This patch keeps original examination of letter validity for reviewability, even though there is redundant interchanging between "chr"/"ord" at initialization of "_syminitletters" and "_symletters". At most 256 times examination (per initialization) is cheaper enough than revset evaluation itself. This patch is a part of preparation for parsing alias declarations and definitions more strictly.

File last commit:

r23583:a8edcb9c default
r23842:91dbb98b default
Show More
subversion.py
1317 lines | 51.7 KiB | text/x-python | PythonLexer
Daniel Holth
convert extension: Add SVN converter
r4765 # Subversion 1.4/1.5 Python API backend
#
# Copyright(C) 2007 Daniel Holth et al
Augie Fackler
convert: move import of xml.minidom.dom to its own line for check-code
r19787 import os, re, sys, tempfile, urllib, urllib2
import xml.dom.minidom
Bryan O'Sullivan
convert/subversion: work around memory leak in svn's python bindings...
r4946 import cPickle as pickle
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
Adrian Buehlmann
move opener from util to scmutil
r13970 from mercurial import strutil, scmutil, util, encoding
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 from mercurial.i18n import _
Daniel Holth
convert extension: Add SVN converter
r4765
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 propertycache = util.propertycache
Daniel Holth
convert extension: Add SVN converter
r4765 # Subversion stuff. Works best with very recent Python SVN bindings
# e.g. SVN 1.5 or backports. Thanks to the bzr folks for enhancing
# these bindings.
from cStringIO import StringIO
Patrick Mezard
convert: improve reporting of invalid svn bindings
r7447 from common import NoRepo, MissingTool, commit, encodeargs, decodeargs
from common import commandline, converter_source, converter_sink, mapfile
Julian Cowley
convert: add config option to use the local time zone...
r17974 from common import makedatetimestamp
Brendan Cully
convert: activate subversion engine...
r4766
try:
from svn.core import SubversionException, Pool
Brendan Cully
convert svn: try to extract URL from source if it is a working directory
r5010 import svn
import svn.client
Brendan Cully
convert: activate subversion engine...
r4766 import svn.core
import svn.ra
import svn.delta
import transport
Ronny Pfannschmidt
convert: hide svn deprecation warnings
r8221 import warnings
warnings.filterwarnings('ignore',
module='svn.core',
category=DeprecationWarning)
Brendan Cully
convert: activate subversion engine...
r4766 except ImportError:
Azhagu Selvan SP
convert/svn: abort operation when python bindings are not available...
r13480 svn = None
Daniel Holth
convert extension: Add SVN converter
r4765
Patrick Mezard
convert: be even more tolerant when detecting svn tags...
r7381 class SvnPathNotFound(Exception):
pass
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 def revsplit(rev):
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 """Parse a revision string and return (uuid, path, revnum).
>>> revsplit('svn:a2147622-4a9f-4db4-a8d3-13562ff547b2'
... '/proj%20B/mytrunk/mytrunk@1')
('a2147622-4a9f-4db4-a8d3-13562ff547b2', '/proj%20B/mytrunk/mytrunk', 1)
>>> revsplit('svn:8af66a51-67f5-4354-b62c-98d67cc7be1d@1')
('', '', 1)
>>> revsplit('@7')
('', '', 7)
>>> revsplit('7')
('', '', 0)
>>> revsplit('bad')
('', '', 0)
"""
parts = rev.rsplit('@', 1)
revnum = 0
if len(parts) > 1:
revnum = int(parts[1])
parts = parts[0].split('/', 1)
uuid = ''
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 mod = ''
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 if len(parts) > 1 and parts[0].startswith('svn:'):
uuid = parts[0][4:]
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 mod = '/' + parts[1]
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 return uuid, mod, revnum
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599 def quote(s):
# As of svn 1.7, many svn calls expect "canonical" paths. In
# theory, we should call svn.core.*canonicalize() on all paths
# before passing them to the API. Instead, we assume the base url
# is canonical and copy the behaviour of svn URL encoding function
# so we can extend it safely with new components. The "safe"
# characters were taken from the "svn_uri__char_validity" table in
# libsvn_subr/path.c.
return urllib.quote(s, "!$&'()*+,-./:=@_~")
Brendan Cully
convert: urlify svn repos if necessary....
r5008 def geturl(path):
Brendan Cully
convert svn: try to extract URL from source if it is a working directory
r5010 try:
Brendan Cully
convert svn: canonicalize path before calling url_from_path....
r5020 return svn.client.url_from_path(svn.core.svn_path_canonicalize(path))
Brendan Cully
convert svn: try to extract URL from source if it is a working directory
r5010 except SubversionException:
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599 # svn.client.url_from_path() fails with local repositories
Brendan Cully
convert svn: try to extract URL from source if it is a working directory
r5010 pass
Brendan Cully
convert: urlify svn repos if necessary....
r5008 if os.path.isdir(path):
Shun-ichi GOTO
convert: Accept local path on win32.
r5793 path = os.path.normpath(os.path.abspath(path))
if os.name == 'nt':
Shun-ichi GOTO
Use util.normpath() instead of direct path string operation....
r5842 path = '/' + util.normpath(path)
Patrick Mezard
convert/svn: stop returning unicode revision identifiers
r8886 # Module URL is later compared with the repository URL returned
# by svn API, which is UTF-8.
path = encoding.tolocal(path)
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599 path = 'file://%s' % quote(path)
return svn.core.svn_path_canonicalize(path)
Brendan Cully
convert: urlify svn repos if necessary....
r5008
Brendan Cully
convert: svn: add helper function for optrevs
r5117 def optrev(number):
optrev = svn.core.svn_opt_revision_t()
optrev.kind = svn.core.svn_opt_revision_number
optrev.value.number = number
return optrev
Bryan O'Sullivan
convert/subversion: work around memory leak in svn's python bindings...
r4946 class changedpath(object):
def __init__(self, p):
self.copyfrom_path = p.copyfrom_path
self.copyfrom_rev = p.copyfrom_rev
self.action = p.action
Brodie Rao
cleanup: eradicate long lines
r16683 def get_log_child(fp, url, paths, start, end, limit=0,
discover_changed_paths=True, strict_node_history=False):
Patrick Mezard
convert: replace fork with subprocess call.
r5127 protocol = -1
def receiver(orig_paths, revnum, author, date, message, pool):
Mads Kiilerich
convert: fix svn crash when svn.ra.get_log calls back with orig_paths=None...
r20057 paths = {}
Patrick Mezard
convert: replace fork with subprocess call.
r5127 if orig_paths is not None:
for k, v in orig_paths.iteritems():
Mads Kiilerich
convert: fix svn crash when svn.ra.get_log calls back with orig_paths=None...
r20057 paths[k] = changedpath(v)
pickle.dump((paths, revnum, author, date, message),
Thomas Arendsen Hein
Remove trailing spaces, fix indentation
r5143 fp, protocol)
Patrick Mezard
convert: replace fork with subprocess call.
r5127 try:
# Use an ra of our own so that our parent can consume
# our results without confusing the server.
t = transport.SvnRaTransport(url=url)
svn.ra.get_log(t.ra, paths, start, end, limit,
discover_changed_paths,
strict_node_history,
receiver)
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 except IOError:
# Caller may interrupt the iteration
pickle.dump(None, fp, protocol)
Matt Mackall
convert: improve exception reporting for SVN logstream...
r15750 except Exception, inst:
pickle.dump(str(inst), fp, protocol)
Patrick Mezard
convert: replace fork with subprocess call.
r5127 else:
pickle.dump(None, fp, protocol)
fp.close()
Patrick Mezard
convert: avoid svn log retrieval process cleanup...
r6397 # With large history, cleanup process goes crazy and suddenly
# consumes *huge* amount of memory. The output file being closed,
# there is no need for clean termination.
os._exit(0)
Patrick Mezard
convert: replace fork with subprocess call.
r5127
Thomas Arendsen Hein
Move debugsvnlog to subversion module.
r5139 def debugsvnlog(ui, **opts):
"""Fetch SVN log in a subprocess and channel them back to parent to
avoid memory collection issues.
"""
Mads Kiilerich
convert: check for failed svn import in debugsvnlog and abort cleanly...
r17053 if svn is None:
raise util.Abort(_('debugsvnlog could not load Subversion python '
'bindings'))
Adrian Buehlmann
rename util.set_binary to setbinary
r14233 util.setbinary(sys.stdin)
util.setbinary(sys.stdout)
Thomas Arendsen Hein
Move debugsvnlog to subversion module.
r5139 args = decodeargs(sys.stdin.read())
get_log_child(sys.stdout, *args)
Benoit Boissinot
use new style classes
r8778 class logstream(object):
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 """Interruptible revision log iterator."""
def __init__(self, stdout):
self._stdout = stdout
def __iter__(self):
while True:
Patrick Mezard
convert/svn: better error when hg cannot call itself (issue1838)
r9587 try:
entry = pickle.load(self._stdout)
except EOFError:
raise util.Abort(_('Mercurial failed to run itself, check'
' hg executable is in PATH'))
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 try:
orig_paths, revnum, author, date, message = entry
Brodie Rao
cleanup: replace naked excepts with more specific ones
r16688 except (TypeError, ValueError):
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 if entry is None:
break
Matt Mackall
convert: improve exception reporting for SVN logstream...
r15750 raise util.Abort(_("log stream exception '%s'") % entry)
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 yield entry
def close(self):
if self._stdout:
self._stdout.close()
self._stdout = None
Mads Kiilerich
convert: secret config option for disabling debugsvnlog...
r20420 class directlogstream(list):
"""Direct revision log iterator.
This can be used for debugging and development but it will probably leak
memory and is not suitable for real conversions."""
def __init__(self, url, paths, start, end, limit=0,
discover_changed_paths=True, strict_node_history=False):
def receiver(orig_paths, revnum, author, date, message, pool):
paths = {}
if orig_paths is not None:
for k, v in orig_paths.iteritems():
paths[k] = changedpath(v)
self.append((paths, revnum, author, date, message))
# Use an ra of our own so that our parent can consume
# our results without confusing the server.
t = transport.SvnRaTransport(url=url)
svn.ra.get_log(t.ra, paths, start, end, limit,
discover_changed_paths,
strict_node_history,
receiver)
def close(self):
pass
Augie Fackler
convert: Improved svn source detection.
r8074
# Check to see if the given path is a local Subversion repo. Verify this by
# looking for several svn-specific files and directories in the given
# directory.
Patrick Mezard
convert/svn: delegate to svn bindings if HTTP probe fails...
r9829 def filecheck(ui, path, proto):
Matt Mackall
many, many trivial check-code fixups
r10282 for x in ('locks', 'hooks', 'format', 'db'):
Augie Fackler
convert: Improved svn source detection.
r8074 if not os.path.exists(os.path.join(path, x)):
return False
return True
# Check to see if a given path is the root of an svn repo over http. We verify
# this by requesting a version-controlled URL we know can't exist and looking
# for the svn-specific "not found" XML.
Patrick Mezard
convert/svn: delegate to svn bindings if HTTP probe fails...
r9829 def httpcheck(ui, path, proto):
try:
opener = urllib2.build_opener()
rsp = opener.open('%s://%s/!svn/ver/0/.svn' % (proto, path))
Matt Mackall
many, many trivial check-code fixups
r10282 data = rsp.read()
Patrick Mezard
convert/svn: delegate to svn bindings if HTTP probe fails...
r9829 except urllib2.HTTPError, inst:
Patrick Mezard
convert/svn: fix HTTP detection bug introduced by 1b2516a547d4...
r9838 if inst.code != 404:
# Except for 404 we cannot know for sure this is not an svn repo
Patrick Mezard
convert/svn: fix warning when repo detection failed
r9860 ui.warn(_('svn: cannot probe remote repository, assume it could '
'be a subversion repository. Use --source-type if you '
'know better.\n'))
Patrick Mezard
convert/svn: fix HTTP detection bug introduced by 1b2516a547d4...
r9838 return True
data = inst.fp.read()
Brodie Rao
cleanup: replace naked excepts with except Exception: ...
r16689 except Exception:
Patrick Mezard
convert/svn: delegate to svn bindings if HTTP probe fails...
r9829 # Could be urllib2.URLError if the URL is invalid or anything else.
return False
Patrick Mezard
convert/svn: fix HTTP detection bug introduced by 1b2516a547d4...
r9838 return '<m:human-readable errcode="160013">' in data
Augie Fackler
convert: Improved svn source detection.
r8074
protomap = {'http': httpcheck,
'https': httpcheck,
'file': filecheck,
}
Patrick Mezard
convert/svn: delegate to svn bindings if HTTP probe fails...
r9829 def issvnurl(ui, url):
Edouard Gomez
convert: default to file protocol when no :// found for svn repo url...
r8764 try:
proto, path = url.split('://', 1)
Grauw
Fix issue 1782 don't do url2pathname conversion for urls...
r9521 if proto == 'file':
Mads Kiilerich
convert: accept Subversion 'file:///c%3A/svnrepo' syntax on Windows...
r17052 if (os.name == 'nt' and path[:1] == '/' and path[1:2].isalpha()
and path[2:6].lower() == '%3a/'):
path = path[:2] + ':/' + path[6:]
Grauw
Fix issue 1782 don't do url2pathname conversion for urls...
r9521 path = urllib.url2pathname(path)
Edouard Gomez
convert: default to file protocol when no :// found for svn repo url...
r8764 except ValueError:
proto = 'file'
path = os.path.abspath(url)
Grauw
Fix issue 1782 don't do url2pathname conversion for urls...
r9521 if proto == 'file':
FUJIWARA Katsunori
i18n: use util.pconvert() instead of 'str.replace()' for problematic encoding...
r16067 path = util.pconvert(path)
Patrick Mezard
convert/subversion: fix default URL checker prototype
r10885 check = protomap.get(proto, lambda *args: False)
Augie Fackler
convert: Improved svn source detection.
r8074 while '/' in path:
Patrick Mezard
convert/svn: delegate to svn bindings if HTTP probe fails...
r9829 if check(ui, path, proto):
Augie Fackler
convert: Improved svn source detection.
r8074 return True
path = path.rsplit('/', 1)[0]
return False
Daniel Holth
convert extension: Add SVN converter
r4765 # SVN conversion code stolen from bzr-svn and tailor
Patrick Mezard
convert: document the subversion conversion model
r5876 #
# Subversion looks like a versioned filesystem, branches structures
# are defined by conventions and not enforced by the tool. First,
# we define the potential branches (modules) as "trunk" and "branches"
# children directories. Revisions are then identified by their
# module and revision number (and a repository identifier).
#
# The revision graph is really a tree (or a forest). By default, a
# revision parent is the previous revision in the same module. If the
# module directory is copied/moved from another module then the
# revision is the module root and its parent the source revision in
# the parent module. A revision has at most one parent.
#
Bryan O'Sullivan
convert: rename convert_svn to svn_source
r5438 class svn_source(converter_source):
Brendan Cully
convert: activate subversion engine...
r4766 def __init__(self, ui, url, rev=None):
Bryan O'Sullivan
convert: rename convert_svn to svn_source
r5438 super(svn_source, self).__init__(ui, url, rev=rev)
Brendan Cully
convert: call superclass init from engine init functions
r4807
Matt Mackall
convert: attempt to check repo type before checking for tool
r7973 if not (url.startswith('svn://') or url.startswith('svn+ssh://') or
(os.path.exists(url) and
os.path.exists(os.path.join(url, '.svn'))) or
Patrick Mezard
convert/svn: delegate to svn bindings if HTTP probe fails...
r9829 issvnurl(ui, url)):
Martin Geisler
convert: mark strings for translation
r10939 raise NoRepo(_("%s does not look like a Subversion repository")
% url)
Azhagu Selvan SP
convert/svn: abort operation when python bindings are not available...
r13480 if svn is None:
Martin Geisler
convert: lowercase status and abort messages
r16925 raise MissingTool(_('could not load Subversion python bindings'))
Patrick Mezard
convert: improve reporting of invalid svn bindings
r7447
try:
version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
if version < (1, 4):
raise MissingTool(_('Subversion python bindings %d.%d found, '
'1.4 or later required') % version)
except AttributeError:
raise MissingTool(_('Subversion python bindings are too old, 1.4 '
'or later required'))
Brendan Cully
convert: activate subversion engine...
r4766
Brendan Cully
convert: svn: use revmap to parse only new revisions in incremental conversions
r4813 self.lastrevs = {}
Brendan Cully
convert: activate subversion engine...
r4766 latest = None
Daniel Holth
convert extension: Add SVN converter
r4765 try:
# Support file://path@rev syntax. Useful e.g. to convert
# deleted branches.
Bryan O'Sullivan
convert/subversion.py: str.rsplit is not available in Python 2.3
r4927 at = url.rfind('@')
if at >= 0:
Matt Mackall
many, many trivial check-code fixups
r10282 latest = int(url[at + 1:])
Bryan O'Sullivan
convert/subversion.py: str.rsplit is not available in Python 2.3
r4927 url = url[:at]
Peter Arrenbrecht
cleanup: drop variables for unused return values...
r7874 except ValueError:
Brendan Cully
convert: activate subversion engine...
r4766 pass
Brendan Cully
convert: urlify svn repos if necessary....
r5008 self.url = geturl(url)
Daniel Holth
convert extension: Add SVN converter
r4765 self.encoding = 'UTF-8' # Subversion is always nominal UTF-8
try:
Brendan Cully
convert: urlify svn repos if necessary....
r5008 self.transport = transport.SvnRaTransport(url=self.url)
Daniel Holth
convert extension: Add SVN converter
r4765 self.ra = self.transport.ra
Bryan O'Sullivan
convert/subversion: work around memory leak in svn's python bindings...
r4946 self.ctx = self.transport.client
Patrick Mezard
convert: properly encode subversion URLs (issue 1224)
r7074 self.baseurl = svn.ra.get_repos_root(self.ra)
Patrick Mezard
convert: fix subpaths detection in svn source
r6538 # Module is either empty or a repository path starting with
# a slash and not ending with a slash.
Patrick Mezard
convert: properly encode subversion URLs (issue 1224)
r7074 self.module = urllib.unquote(self.url[len(self.baseurl):])
Patrick Mezard
convert: restore previous svn transport parent correctly
r6847 self.prevmodule = None
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 self.rootmodule = self.module
Daniel Holth
convert extension: Add SVN converter
r4765 self.commits = {}
Brendan Cully
convert: look up copies in getchanges instead of getcommit...
r5121 self.paths = {}
Patrick Mezard
convert/svn: stop returning unicode revision identifiers
r8886 self.uuid = svn.ra.get_uuid(self.ra)
Peter Arrenbrecht
cleanup: drop unused assignments
r7875 except SubversionException:
Matt Mackall
ui: print_exc() -> traceback()
r8206 ui.traceback()
Augie Fackler
convert: on svn failure, note libsvn version (issue4043)...
r23583 svnversion = '%d.%d.%d' % (svn.core.SVN_VER_MAJOR,
svn.core.SVN_VER_MINOR,
svn.core.SVN_VER_MICRO)
raise NoRepo(_("%s does not look like a Subversion repository "
"to libsvn version %s")
% (self.url, svnversion))
Daniel Holth
convert extension: Add SVN converter
r4765
Thomas Arendsen Hein
raise util.Abort again if specified revision is not an integer....
r5145 if rev:
try:
latest = int(rev)
except ValueError:
Martin Geisler
i18n: mark strings for translation in convert extension
r6956 raise util.Abort(_('svn: revision %s is not an integer') % rev)
Thomas Arendsen Hein
raise util.Abort again if specified revision is not an integer....
r5145
Brodie Rao
cleanup: eradicate long lines
r16683 self.trunkname = self.ui.config('convert', 'svn.trunk',
'trunk').strip('/')
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 self.startrev = self.ui.config('convert', 'svn.startrev', default=0)
try:
self.startrev = int(self.startrev)
if self.startrev < 0:
self.startrev = 0
except ValueError:
Thomas Arendsen Hein
Removed trailing spaces from everything except test output
r6210 raise util.Abort(_('svn: start revision %s is not an integer')
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 % self.startrev)
Mads Kiilerich
convert: handle invalid subversion source paths
r14152 try:
self.head = self.latest(self.module, latest)
except SvnPathNotFound:
self.head = None
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 if not self.head:
Patrick Mezard
convert/svn: stop returning unicode revision identifiers
r8886 raise util.Abort(_('no revision found in module %s')
% self.module)
Patrick Mezard
convert: fix svn_source.latest()
r5955 self.last_changed = self.revnum(self.head)
Thomas Arendsen Hein
Removed trailing spaces from everything except test output
r6210
Mads Kiilerich
convert: refactor subversion getchanges and caching
r22298 self._changescache = (None, None)
Daniel Holth
convert extension: Add SVN converter
r4765
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554 if os.path.exists(os.path.join(url, '.svn/entries')):
self.wc = url
else:
self.wc = None
self.convertfp = None
Bryan O'Sullivan
convert: abstract map files into a class
r5510 def setrevmap(self, revmap):
Brendan Cully
convert: svn code movement (no actual changes)
r4840 lastrevs = {}
Bryan O'Sullivan
convert: iterate
r5511 for revid in revmap.iterkeys():
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 uuid, module, revnum = revsplit(revid)
Brendan Cully
convert: svn code movement (no actual changes)
r4840 lastrevnum = lastrevs.setdefault(module, revnum)
if revnum > lastrevnum:
lastrevs[module] = revnum
self.lastrevs = lastrevs
Bryan O'Sullivan
convert/subversion.py: fix bad assumptions about SVN path naming...
r4925 def exists(self, path, optrev):
try:
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599 svn.client.ls(self.url.rstrip('/') + '/' + quote(path),
Bryan O'Sullivan
convert/subversion.py: fix bad assumptions about SVN path naming...
r4925 optrev, False, self.ctx)
Kirill Smelkov
convert: svn -- fix 'exists'...
r5461 return True
Peter Arrenbrecht
cleanup: drop unused assignments
r7875 except SubversionException:
Kirill Smelkov
convert: svn -- fix 'exists'...
r5461 return False
Bryan O'Sullivan
convert/subversion.py: fix bad assumptions about SVN path naming...
r4925
Brendan Cully
convert: svn code movement (no actual changes)
r4840 def getheads(self):
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854
Patrick Mezard
convert: check svn branches are directories
r6491 def isdir(path, revnum):
Patrick Mezard
convert: remove leading slash from ra.check_path inputs (issue 1236)
r6848 kind = self._checkpath(path, revnum)
Patrick Mezard
convert: check svn branches are directories
r6491 return kind == svn.core.svn_node_dir
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 def getcfgpath(name, rev):
cfgpath = self.ui.config('convert', 'svn.' + name)
Patrick Mezard
convert: allow svn trunk/branches/tags detection to be skipped...
r6172 if cfgpath is not None and cfgpath.strip() == '':
return None
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 path = (cfgpath or name).strip('/')
if not self.exists(path, rev):
Pavel Boldin
convert.svn: branch name which equals trunk means `default' branch (issue2653)...
r13494 if self.module.endswith(path) and name == 'trunk':
# we are converting from inside this directory
return None
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 if cfgpath:
raise util.Abort(_('expected %s to be at %r, but not found')
% (name, path))
return None
self.ui.note(_('found %s at %r\n') % (name, path))
return path
Brendan Cully
convert: svn: add helper function for optrevs
r5117 rev = optrev(self.last_changed)
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 oldmodule = ''
trunk = getcfgpath('trunk', rev)
Patrick Mezard
convert: allow tags detection to be disabled...
r6400 self.tags = getcfgpath('tags', rev)
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 branches = getcfgpath('branches', rev)
# If the project has a trunk or branches, we will extract heads
# from them. We keep the project root otherwise.
if trunk:
oldmodule = self.module or ''
Bryan O'Sullivan
convert/subversion.py: fix bad assumptions about SVN path naming...
r4925 self.module += '/' + trunk
Patrick Mezard
convert: fix svn_source.latest()
r5955 self.head = self.latest(self.module, self.last_changed)
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 if not self.head:
Dirkjan Ochtman
kill trailing whitespace
r9312 raise util.Abort(_('no revision found in module %s')
Patrick Mezard
convert/svn: stop returning unicode revision identifiers
r8886 % self.module)
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854
# First head in the list is the module's head
self.heads = [self.head]
Patrick Mezard
convert: allow tags detection to be disabled...
r6400 if self.tags is not None:
self.tags = '%s/%s' % (oldmodule , (self.tags or 'tags'))
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854
# Check if branches bring a few more heads to the list
if branches:
rpath = self.url.strip('/')
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599 branchnames = svn.client.ls(rpath + '/' + quote(branches),
Patrick Mezard
convert: properly encode subversion URLs (issue 1224)
r7074 rev, False, self.ctx)
Mads Kiilerich
convert: process subversion branch in a sorted order
r18374 for branch in sorted(branchnames):
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 module = '%s/%s/%s' % (oldmodule, branches, branch)
Patrick Mezard
convert: check svn branches are directories
r6491 if not isdir(module, self.last_changed):
continue
Patrick Mezard
convert: fix svn_source.latest()
r5955 brevid = self.latest(module, self.last_changed)
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 if not brevid:
Patrick Mezard
convert/svn: stop returning unicode revision identifiers
r8886 self.ui.note(_('ignoring empty branch %s\n') % branch)
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 continue
Martin Geisler
i18n: mark strings for translation in convert extension
r6956 self.ui.note(_('found branch %s at %d\n') %
Patrick Mezard
convert: fix svn_source.latest()
r5955 (branch, self.revnum(brevid)))
self.heads.append(brevid)
Kirill Smelkov
convert: svn -- fix tags handling...
r5462
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 if self.startrev and self.heads:
if len(self.heads) > 1:
Wagner Bruna
convert: fix typo
r8086 raise util.Abort(_('svn: start revision is not supported '
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 'with more than one branch'))
revnum = self.revnum(self.heads[0])
if revnum < self.startrev:
Matt Mackall
many, many trivial check-code fixups
r10282 raise util.Abort(
_('svn: no revision found after start revision %d')
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 % self.startrev)
Brendan Cully
convert: svn code movement (no actual changes)
r4840 return self.heads
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 def _getchanges(self, rev, full):
Brendan Cully
convert: look up copies in getchanges instead of getcommit...
r5121 (paths, parents) = self.paths[rev]
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 copies = {}
Patrick Mezard
convert: checkout svn root revisions...
r5956 if parents:
Patrick Mezard
convert/svn: do not retrieve removed files...
r11127 files, self.removed, copies = self.expandpaths(rev, paths, parents)
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 if full or not parents:
Patrick Mezard
convert: checkout svn root revisions...
r5956 # Perform a full checkout on roots
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 uuid, module, revnum = revsplit(rev)
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599 entries = svn.client.ls(self.baseurl + quote(module),
Patrick Mezard
convert: properly encode subversion URLs (issue 1224)
r7074 optrev(revnum), True, self.ctx)
Matt Mackall
many, many trivial check-code fixups
r10282 files = [n for n, e in entries.iteritems()
Patrick Mezard
convert: checkout svn root revisions...
r5956 if e.kind == svn.core.svn_node_file]
Patrick Mezard
convert/svn: do not retrieve removed files...
r11127 self.removed = set()
Patrick Mezard
convert: checkout svn root revisions...
r5956
Brendan Cully
convert: look up copies in getchanges instead of getcommit...
r5121 files.sort()
files = zip(files, [rev] * len(files))
Mads Kiilerich
convert: refactor subversion getchanges and caching
r22298 return (files, copies)
Brendan Cully
convert: look up copies in getchanges instead of getcommit...
r5121
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 def getchanges(self, rev, full):
Mads Kiilerich
convert: refactor subversion getchanges and caching
r22298 # reuse cache from getchangedfiles
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 if self._changescache[0] == rev and not full:
Mads Kiilerich
convert: refactor subversion getchanges and caching
r22298 (files, copies) = self._changescache[1]
else:
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 (files, copies) = self._getchanges(rev, full)
Mads Kiilerich
convert: refactor subversion getchanges and caching
r22298 # caller caches the result, so free it here to release memory
del self.paths[rev]
Brendan Cully
convert: look up copies in getchanges instead of getcommit...
r5121 return (files, copies)
Brendan Cully
convert: svn code movement (no actual changes)
r4840
Alexis S. L. Carvalho
convert_svn: add --filemap support
r5382 def getchangedfiles(self, rev, i):
Mads Kiilerich
convert: refactor subversion getchanges and caching
r22298 # called from filemap - cache computed values for reuse in getchanges
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 (files, copies) = self._getchanges(rev, False)
Mads Kiilerich
convert: refactor subversion getchanges and caching
r22298 self._changescache = (rev, (files, copies))
return [f[0] for f in files]
Alexis S. L. Carvalho
convert_svn: add --filemap support
r5382
Brendan Cully
convert: svn code movement (no actual changes)
r4840 def getcommit(self, rev):
if rev not in self.commits:
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 uuid, module, revnum = revsplit(rev)
Brendan Cully
convert: svn code movement (no actual changes)
r4840 self.module = module
self.reparent(module)
Patrick Mezard
convert: fetch less revisions when looking for a branch parent
r5875 # We assume that:
# - requests for revisions after "stop" come from the
# revision graph backward traversal. Cache all of them
# down to stop, they will be used eventually.
# - requests for revisions before "stop" come to get
# isolated branches parents. Just fetch what is needed.
Brendan Cully
convert: svn code movement (no actual changes)
r4840 stop = self.lastrevs.get(module, 0)
Patrick Mezard
convert: fetch less revisions when looking for a branch parent
r5875 if revnum < stop:
stop = revnum + 1
Patrick Mezard
convert: fix parents of last fetched svn revision
r5871 self._fetch_revisions(revnum, stop)
Jesus Espino Garcia
convert: subversion convert abort on revision not found (issue 3205)
r15970 if rev not in self.commits:
raise util.Abort(_('svn: revision %s not found') % revnum)
Mads Kiilerich
cleanup: fix some list comprehension redefinitions of existing vars...
r22201 revcommit = self.commits[rev]
Brendan Cully
convert: svn code movement (no actual changes)
r4840 # caller caches the result, so free it here to release memory
del self.commits[rev]
Mads Kiilerich
cleanup: fix some list comprehension redefinitions of existing vars...
r22201 return revcommit
Brendan Cully
convert: svn code movement (no actual changes)
r4840
Sean Farley
convert: add mapname parameter to checkrevformat...
r20373 def checkrevformat(self, revstr, mapname='splicemap'):
Ben Goswami
splicemap: improve error handling when source is subversion (issue2084)...
r19122 """ fails if revision format does not match the correct format"""
if not re.match(r'svn:[0-9a-f]{8,8}-[0-9a-f]{4,4}-'
'[0-9a-f]{4,4}-[0-9a-f]{4,4}-[0-9a-f]'
'{12,12}(.*)\@[0-9]+$',revstr):
Sean Farley
convert: add mapname parameter to checkrevformat...
r20373 raise util.Abort(_('%s entry %s is not a valid revision'
' identifier') % (mapname, revstr))
Ben Goswami
splicemap: improve error handling when source is subversion (issue2084)...
r19122
Augie Fackler
convert: enable deterministic conversion progress bar for svn...
r22414 def numcommits(self):
return int(self.head.rsplit('@', 1)[1]) - self.startrev
Brendan Cully
convert: svn code movement (no actual changes)
r4840 def gettags(self):
tags = {}
Patrick Mezard
convert: allow svn trunk/branches/tags detection to be skipped...
r6172 if self.tags is None:
return tags
Thomas Arendsen Hein
Removed trailing spaces from everything except test output
r6210
Patrick Mezard
convert: follow svn tags history (issue953)
r6399 # svn tags are just a convention, project branches left in a
# 'tags' directory. There is no other relationship than
# ancestry, which is expensive to discover and makes them hard
# to update incrementally. Worse, past revisions may be
# referenced by tags far away in the future, requiring a deep
# history traversal on every calculation. Current code
# performs a single backward traversal, tracking moves within
# the tags directory (tag renaming) and recording a new tag
# everytime a project is copied from outside the tags
# directory. It also lists deleted tags, this behaviour may
# change in the future.
pendings = []
tagspath = self.tags
start = svn.ra.get_latest_revnum(self.ra)
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 stream = self._getlog([self.tags], start, self.startrev)
try:
for entry in stream:
origpaths, revnum, author, date, message = entry
Matt Mackall
convert: catch empty origpaths in svn gettags (issue3941)
r19468 if not origpaths:
origpaths = []
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p, e
in origpaths.iteritems() if e.copyfrom_path]
# Apply moves/copies from more specific to general
copies.sort(reverse=True)
Patrick Mezard
convert: follow svn tags history (issue953)
r6399
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 srctagspath = tagspath
if copies and copies[-1][2] == tagspath:
# Track tags directory moves
srctagspath = copies.pop()[0]
Patrick Mezard
convert: follow svn tags history (issue953)
r6399
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 for source, sourcerev, dest in copies:
if not dest.startswith(tagspath + '/'):
continue
for tag in pendings:
if tag[0].startswith(dest):
tagpath = source + tag[0][len(dest):]
tag[:2] = [tagpath, sourcerev]
break
else:
pendings.append([source, sourcerev, dest])
Patrick Mezard
convert/svn: ignore composite tags...
r8248
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 # Filter out tags with children coming from different
# parts of the repository like:
# /tags/tag.1 (from /trunk:10)
# /tags/tag.1/foo (from /branches/foo:12)
# Here/tags/tag.1 discarded as well as its children.
# It happens with tools like cvs2svn. Such tags cannot
# be represented in mercurial.
addeds = dict((p, e.copyfrom_path) for p, e
in origpaths.iteritems()
if e.action == 'A' and e.copyfrom_path)
badroots = set()
for destroot in addeds:
for source, sourcerev, dest in pendings:
if (not dest.startswith(destroot + '/')
or source.startswith(addeds[destroot] + '/')):
continue
badroots.add(destroot)
break
Patrick Mezard
convert/svn: ignore composite tags...
r8248
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 for badroot in badroots:
pendings = [p for p in pendings if p[2] != badroot
and not p[2].startswith(badroot + '/')]
Patrick Mezard
convert: follow svn tags history (issue953)
r6399
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 # Tell tag renamings from tag creations
Martin Geisler
convert: rename local variable
r15124 renamings = []
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 for source, sourcerev, dest in pendings:
tagname = dest.split('/')[-1]
if source.startswith(srctagspath):
Martin Geisler
convert: rename local variable
r15124 renamings.append([source, sourcerev, tagname])
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 continue
if tagname in tags:
# Keep the latest tag value
continue
# From revision may be fake, get one with changes
try:
tagid = self.latest(source, sourcerev)
if tagid and tagname not in tags:
tags[tagname] = tagid
except SvnPathNotFound:
# It happens when we are following directories
# we assumed were copied with their parents
# but were really created in the tag
# directory.
pass
Martin Geisler
convert: rename local variable
r15124 pendings = renamings
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 tagspath = srctagspath
finally:
stream.close()
Bryan O'Sullivan
convert/subversion: work around memory leak in svn's python bindings...
r4946 return tags
Brendan Cully
convert: svn code movement (no actual changes)
r4840
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554 def converted(self, rev, destrev):
if not self.wc:
return
if self.convertfp is None:
self.convertfp = open(os.path.join(self.wc, '.svn', 'hg-shamap'),
'a')
self.convertfp.write('%s %d\n' % (destrev, self.revnum(rev)))
self.convertfp.flush()
Brendan Cully
convert: move some code into common init function
r4810 def revid(self, revnum, module=None):
Patrick Mezard
convert/svn: stop returning unicode revision identifiers
r8886 return 'svn:%s%s@%s' % (self.uuid, module or self.module, revnum)
Brendan Cully
convert: svn: add revnum() to convert rev to revnum
r4774
def revnum(self, rev):
return int(rev.split('@')[-1])
Brendan Cully
convert: svn: add function to get the latest revision touching a path...
r4789
Patrick Mezard
convert/svn: clarify svn_source.latest() stop arg default value...
r16464 def latest(self, path, stop=None):
"""Find the latest revid affecting path, up to stop revision
number. If stop is None, default to repository latest
revision. It may return a revision in a different module,
since a branch may be moved without a change being
reported. Return None if computed module does not belong to
rootmodule subtree.
Patrick Mezard
convert: fix svn_source.latest()
r5955 """
Patrick Mezard
convert/svn: do not try converting empty head revisions (issue3347)...
r16466 def findchanges(path, start, stop=None):
stream = self._getlog([path], start, stop or 1)
Patrick Mezard
convert/svn: refactor svn_source.latest() with a nested function...
r16465 try:
for entry in stream:
paths, revnum, author, date, message = entry
Patrick Mezard
convert/svn: do not try converting empty head revisions (issue3347)...
r16466 if stop is None and paths:
# We do not know the latest changed revision,
# keep the first one with changed paths.
break
Patrick Mezard
convert/svn: refactor svn_source.latest() with a nested function...
r16465 if revnum <= stop:
break
for p in paths:
if (not path.startswith(p) or
not paths[p].copyfrom_path):
continue
newpath = paths[p].copyfrom_path + path[len(p):]
self.ui.debug("branch renamed from %s to %s at %d\n" %
(path, newpath, revnum))
path = newpath
break
Patrick Mezard
convert/svn: do not try converting empty head revisions (issue3347)...
r16466 if not paths:
revnum = None
Patrick Mezard
convert/svn: refactor svn_source.latest() with a nested function...
r16465 return revnum, path
finally:
stream.close()
Patrick Mezard
convert: avoid querying log of foreign svn branches...
r6281 if not path.startswith(self.rootmodule):
# Requests on foreign branches may be forbidden at server level
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('ignoring foreign branch %r\n' % path)
Patrick Mezard
convert: avoid querying log of foreign svn branches...
r6281 return None
Patrick Mezard
convert/svn: clarify svn_source.latest() stop arg default value...
r16464 if stop is None:
Brendan Cully
convert: svn: add function to get the latest revision touching a path...
r4789 stop = svn.ra.get_latest_revnum(self.ra)
try:
Patrick Mezard
convert: restore previous svn transport parent correctly
r6847 prevmodule = self.reparent('')
Brendan Cully
convert: svn: add function to get the latest revision touching a path...
r4789 dirent = svn.ra.stat(self.ra, path.strip('/'), stop)
Patrick Mezard
convert: restore previous svn transport parent correctly
r6847 self.reparent(prevmodule)
Brendan Cully
convert: svn: add function to get the latest revision touching a path...
r4789 except SubversionException:
dirent = None
if not dirent:
Matt Mackall
many, many trivial check-code fixups
r10282 raise SvnPathNotFound(_('%s not found up to revision %d')
% (path, stop))
Brendan Cully
convert: svn: add function to get the latest revision touching a path...
r4789
Martin Geisler
convert/subversion: wrap long lines in comments
r8660 # stat() gives us the previous revision on this line of
# development, but it might be in *another module*. Fetch the
# log and detect renames down to the latest revision.
Patrick Mezard
convert/svn: refactor svn_source.latest() with a nested function...
r16465 revnum, realpath = findchanges(path, stop, dirent.created_rev)
Patrick Mezard
convert/svn: do not try converting empty head revisions (issue3347)...
r16466 if revnum is None:
# Tools like svnsync can create empty revision, when
# synchronizing only a subtree for instance. These empty
# revisions created_rev still have their original values
# despite all changes having disappeared and can be
# returned by ra.stat(), at least when stating the root
# module. In that case, do not trust created_rev and scan
# the whole history.
revnum, realpath = findchanges(path, stop)
if revnum is None:
self.ui.debug('ignoring empty branch %r\n' % realpath)
return None
Patrick Mezard
convert/svn: refactor svn_source.latest() with a nested function...
r16465 if not realpath.startswith(self.rootmodule):
self.ui.debug('ignoring foreign branch %r\n' % realpath)
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 return None
Patrick Mezard
convert/svn: refactor svn_source.latest() with a nested function...
r16465 return self.revid(revnum, realpath)
Brendan Cully
convert: svn: add function to get the latest revision touching a path...
r4789
Daniel Holth
convert extension: Add SVN converter
r4765 def reparent(self, module):
Patrick Mezard
convert: restore previous svn transport parent correctly
r6847 """Reparent the svn transport and return the previous parent."""
if self.prevmodule == module:
return module
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599 svnurl = self.baseurl + quote(module)
Patrick Mezard
convert: restore previous svn transport parent correctly
r6847 prevmodule = self.prevmodule
if prevmodule is None:
prevmodule = ''
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug("reparent to %s\n" % svnurl)
Patrick Mezard
convert: properly encode subversion URLs (issue 1224)
r7074 svn.ra.reparent(self.ra, svnurl)
Patrick Mezard
convert: restore previous svn transport parent correctly
r6847 self.prevmodule = module
return prevmodule
Daniel Holth
convert extension: Add SVN converter
r4765
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 def expandpaths(self, rev, paths, parents):
Patrick Mezard
convert/svn: do not retrieve removed files...
r11127 changed, removed = set(), set()
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 copies = {}
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 new_module, revnum = revsplit(rev)[1:]
Patrick Mezard
convert: fix cross-branches subversion revisions handling...
r5872 if new_module != self.module:
self.module = new_module
self.reparent(self.module)
Brendan Cully
convert: look up copies in getchanges instead of getcommit...
r5121
Patrick Mezard
convert/svn: report path discovery progress...
r11137 for i, (path, ent) in enumerate(paths):
self.ui.progress(_('scanning paths'), i, item=path,
total=len(paths))
Patrick Mezard
convert: rename get_entry_from_path() into an svn_source method
r6539 entrypath = self.getrelpath(path)
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120
Patrick Mezard
convert: remove leading slash from ra.check_path inputs (issue 1236)
r6848 kind = self._checkpath(entrypath, revnum)
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 if kind == svn.core.svn_node_file:
Patrick Mezard
convert/svn: do not retrieve removed files...
r11127 changed.add(self.recode(entrypath))
Patrick Mezard
convert: fix svn file copy detection code
r6546 if not ent.copyfrom_path or not parents:
Patrick Mezard
convert: cleanup svn file copy handling
r6544 continue
Martin Geisler
convert/subversion: wrap long lines in comments
r8660 # Copy sources not in parent revisions cannot be
# represented, ignore their origin for now
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 pmodule, prevnum = revsplit(parents[0])[1:]
Patrick Mezard
convert: fix svn file copy detection code
r6546 if ent.copyfrom_rev < prevnum:
continue
copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule)
Patrick Mezard
convert: cleanup svn file copy handling
r6544 if not copyfrom_path:
continue
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug("copied to %s from %s@%s\n" %
Patrick Mezard
convert: cleanup svn file copy handling
r6544 (entrypath, copyfrom_path, ent.copyfrom_rev))
Patrick Mezard
convert/svn: remove confusing unicode variable
r8885 copies[self.recode(entrypath)] = self.recode(copyfrom_path)
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 elif kind == 0: # gone, but had better be a deleted *file*
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 pmodule, prevnum = revsplit(parents[0])[1:]
Patrick Mezard
convert/svn: remove dead code from entry deletion code path...
r8884 parentpath = pmodule + "/" + entrypath
Patrick Mezard
convert/svn: handle files/links replaced by dirs (issue2166)
r11128 fromkind = self._checkpath(entrypath, prevnum, pmodule)
Thomas Arendsen Hein
Removed trailing spaces from everything except test output
r6210
Patrick Mezard
convert/svn: remove dead code and obsolete comments
r8881 if fromkind == svn.core.svn_node_file:
Patrick Mezard
convert/svn: do not retrieve removed files...
r11127 removed.add(self.recode(entrypath))
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 elif fromkind == svn.core.svn_node_dir:
Patrick Mezard
convert/svn: tree conflicts no longer happen now we use memctx
r11123 oroot = parentpath.strip('/')
nroot = path.strip('/')
Patrick Mezard
convert/svn: remove useless sort
r11133 children = self._iterfiles(oroot, prevnum)
Patrick Mezard
convert/svn: list files explicitely, stop checking their type...
r11132 for childpath in children:
childpath = childpath.replace(oroot, nroot)
childpath = self.getrelpath("/" + childpath, pmodule)
Patrick Mezard
convert/svn: remove broken but unused copy filtering code...
r11125 if childpath:
Patrick Mezard
convert/svn: do not retrieve removed files...
r11127 removed.add(self.recode(childpath))
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 else:
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('unknown path in revision %d: %s\n' % \
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 (revnum, path))
Martin Geisler
check-code: find trailing whitespace
r12770 elif kind == svn.core.svn_node_dir:
Patrick Mezard
convert: don't scan directories on property changes
r5870 if ent.action == 'M':
Patrick Mezard
convert/svn: handle files/links replaced by dirs (issue2166)
r11128 # If the directory just had a prop change,
# then we shouldn't need to look for its children.
Patrick Mezard
convert: don't scan directories on property changes
r5870 continue
Patrick Mezard
convert/svn: fix changed files list upon directory replacements...
r13052 if ent.action == 'R' and parents:
Patrick Mezard
convert/svn: handle files/links replaced by dirs (issue2166)
r11128 # If a directory is replacing a file, mark the previous
# file as deleted
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 pmodule, prevnum = revsplit(parents[0])[1:]
Patrick Mezard
convert/svn: handle files/links replaced by dirs (issue2166)
r11128 pkind = self._checkpath(entrypath, prevnum, pmodule)
if pkind == svn.core.svn_node_file:
removed.add(self.recode(entrypath))
Patrick Mezard
convert/svn: fix changed files list upon directory replacements...
r13052 elif pkind == svn.core.svn_node_dir:
# We do not know what files were kept or removed,
# mark them all as changed.
for childpath in self._iterfiles(pmodule, prevnum):
childpath = self.getrelpath("/" + childpath)
if childpath:
changed.add(self.recode(childpath))
Patrick Mezard
convert: don't scan directories on property changes
r5870
Patrick Mezard
convert/svn: remove useless sort
r11133 for childpath in self._iterfiles(path, revnum):
Patrick Mezard
convert/svn: list files explicitely, stop checking their type...
r11132 childpath = self.getrelpath("/" + childpath)
if childpath:
changed.add(self.recode(childpath))
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120
Patrick Mezard
convert/svn: remove dead code and obsolete comments
r8881 # Handle directory copies
Patrick Mezard
convert: handle past or foreign partial svn copies...
r6543 if not ent.copyfrom_path or not parents:
Patrick Mezard
convert: more cleanup in svn directory copy handling
r6542 continue
Martin Geisler
convert/subversion: wrap long lines in comments
r8660 # Copy sources not in parent revisions cannot be
# represented, ignore their origin for now
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 pmodule, prevnum = revsplit(parents[0])[1:]
Patrick Mezard
convert: handle past or foreign partial svn copies...
r6543 if ent.copyfrom_rev < prevnum:
continue
Patrick Mezard
convert/svn: remove useless encoding/decoding calls (issue1676)
r8882 copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule)
Patrick Mezard
convert: more cleanup in svn directory copy handling
r6542 if not copyfrompath:
continue
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug("mark %s came from %s:%d\n"
Patrick Mezard
convert: more cleanup in svn directory copy handling
r6542 % (path, copyfrompath, ent.copyfrom_rev))
Patrick Mezard
convert/svn: remove useless sort
r11133 children = self._iterfiles(ent.copyfrom_path, ent.copyfrom_rev)
Patrick Mezard
convert/svn: list files explicitely, stop checking their type...
r11132 for childpath in children:
childpath = self.getrelpath("/" + childpath, pmodule)
if not childpath:
Patrick Mezard
convert: more cleanup in svn directory copy handling
r6542 continue
Patrick Mezard
convert/svn: list files explicitely, stop checking their type...
r11132 copytopath = path + childpath[len(copyfrompath):]
Patrick Mezard
convert: more cleanup in svn directory copy handling
r6542 copytopath = self.getrelpath(copytopath)
Patrick Mezard
convert/svn: list files explicitely, stop checking their type...
r11132 copies[self.recode(copytopath)] = self.recode(childpath)
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120
Patrick Mezard
convert/svn: report path discovery progress...
r11137 self.ui.progress(_('scanning paths'), None)
Patrick Mezard
convert/svn: do not retrieve removed files...
r11127 changed.update(removed)
return (list(changed), removed, copies)
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120
Patrick Mezard
convert: fix parents of last fetched svn revision
r5871 def _fetch_revisions(self, from_revnum, to_revnum):
if from_revnum < to_revnum:
from_revnum, to_revnum = to_revnum, from_revnum
Bryan O'Sullivan
convert/subversion: reduce memory usage by filtering early...
r4940 self.child_cset = None
Patrick Mezard
convert: fix svn branch source detection corner case...
r6545
Bryan O'Sullivan
convert/subversion: work around memory leak in svn's python bindings...
r4946 def parselogentry(orig_paths, revnum, author, date, message):
Thomas Arendsen Hein
Removed trailing spaces from everything except test output
r6210 """Return the parsed commit object or None, and True if
Patrick Mezard
convert: fix cross-branches subversion revisions handling...
r5872 the revision is a branch root.
"""
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug("parsing revision %d (%d changes)\n" %
Bryan O'Sullivan
convert/subversion: work around memory leak in svn's python bindings...
r4946 (revnum, len(orig_paths)))
Bryan O'Sullivan
convert/subversion: reduce memory usage by filtering early...
r4940
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 branched = False
Brendan Cully
convert: move some code into common init function
r4810 rev = self.revid(revnum)
Brendan Cully
convert: svn: some improvements in memory usage
r4837 # branch log might return entries for a parent we already have
Patrick Mezard
convert: fix parents of last fetched svn revision
r5871
Martin Geisler
remove unnecessary outer parenthesis in if-statements
r8117 if rev in self.commits or revnum < to_revnum:
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 return None, branched
Brendan Cully
convert: svn: some improvements in memory usage
r4837
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 parents = []
Patrick Mezard
convert: follow svn module parent moves
r5958 # check whether this revision is the start of a branch or part
# of a branch renaming
Matt Mackall
replace util.sort with sorted built-in...
r8209 orig_paths = sorted(orig_paths.iteritems())
Matt Mackall
many, many trivial check-code fixups
r10282 root_paths = [(p, e) for p, e in orig_paths
if self.module.startswith(p)]
Patrick Mezard
convert: follow svn module parent moves
r5958 if root_paths:
path, ent = root_paths[-1]
Brendan Cully
convert: svn: hoist up branch creation check
r5119 if ent.copyfrom_path:
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 branched = True
Patrick Mezard
convert: follow svn module parent moves
r5958 newpath = ent.copyfrom_path + self.module[len(path):]
Brendan Cully
convert: svn: hoist up branch creation check
r5119 # ent.copyfrom_rev may not be the actual last revision
Patrick Mezard
convert: backout a7492fb2107b...
r7476 previd = self.latest(newpath, ent.copyfrom_rev)
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 if previd is not None:
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 prevmodule, prevnum = revsplit(previd)[1:]
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 if prevnum >= self.startrev:
parents = [previd]
Matt Mackall
many, many trivial check-code fixups
r10282 self.ui.note(
_('found parent of branch %s at %d: %s\n') %
(self.module, prevnum, prevmodule))
Brendan Cully
convert: svn: hoist up branch creation check
r5119 else:
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug("no copyfrom path, don't know what to do.\n")
Brendan Cully
convert: svn: hoist up branch creation check
r5119
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 paths = []
# filter out unrelated paths
Bryan O'Sullivan
convert/subversion: reduce memory usage by filtering early...
r4940 for path, ent in orig_paths:
Patrick Mezard
convert: improve subversion branch filtering
r6540 if self.getrelpath(path) is None:
Brendan Cully
convert: svn: add an early return to move most changeset parsing out an indent level
r4788 continue
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 paths.append((path, ent))
Daniel Holth
convert extension: Add SVN converter
r4765
Brendan Cully
convert: svn: add an early return to move most changeset parsing out an indent level
r4788 # Example SVN datetime. Includes microseconds.
# ISO-8601 conformant
# '2007-01-04T17:35:00.902377Z'
David J. Mellor
convert: fix SVN date parser dropping the final whole second digit
r5617 date = util.parsedate(date[:19] + " UTC", ["%Y-%m-%dT%H:%M:%S"])
Julian Cowley
convert: add config option to use the local time zone...
r17974 if self.ui.configbool('convert', 'localtimezone'):
date = makedatetimestamp(date[0])
Daniel Holth
convert extension: Add SVN converter
r4765
Thomas Arendsen Hein
convert: Do not abort with TypeError if svn commit message is None (issue934)
r5916 log = message and self.recode(message) or ''
Brendan Cully
convert: svn: add an early return to move most changeset parsing out an indent level
r4788 author = author and self.recode(author) or ''
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 try:
branch = self.module.split("/")[-1]
Patrick Mezard
convert/svn: read trunk name once, use None for default
r13529 if branch == self.trunkname:
branch = None
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 except IndexError:
branch = None
Daniel Holth
convert extension: Add SVN converter
r4765
Brendan Cully
convert: svn: add an early return to move most changeset parsing out an indent level
r4788 cset = commit(author=author,
FUJIWARA Katsunori
i18n: use locale insensitive format for datetimes as intermediate representation (issue3398)...
r16514 date=util.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
Thomas Arendsen Hein
removed trailing whitespace
r4957 desc=log,
Brendan Cully
convert: svn: get parent for branch creation events
r4795 parents=parents,
Brendan Cully
convert: record the source revision in the changelog
r4873 branch=branch,
Patrick Mezard
convert/svn: stop returning unicode revision identifiers
r8886 rev=rev)
Brendan Cully
convert: svn: add an early return to move most changeset parsing out an indent level
r4788
Brendan Cully
convert: svn: pull out broken batching code, add alpha tags support
r4796 self.commits[rev] = cset
Patrick Mezard
convert: fix cross-branches subversion revisions handling...
r5872 # The parents list is *shared* among self.paths and the
# commit object. Both will be updated below.
self.paths[rev] = (paths, cset.parents)
Brendan Cully
convert: svn: pull out broken batching code, add alpha tags support
r4796 if self.child_cset and not self.child_cset.parents:
Patrick Mezard
convert: fix cross-branches subversion revisions handling...
r5872 self.child_cset.parents[:] = [rev]
Brendan Cully
convert: svn: add an early return to move most changeset parsing out an indent level
r4788 self.child_cset = cset
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 return cset, branched
Brendan Cully
convert: svn: pull out broken batching code, add alpha tags support
r4796
Martin Geisler
i18n: mark strings for translation in convert extension
r6956 self.ui.note(_('fetching revision log for "%s" from %d to %d\n') %
Brendan Cully
convert: svn: autodetect /branches, /tags, /trunk....
r4797 (self.module, from_revnum, to_revnum))
Daniel Holth
convert extension: Add SVN converter
r4765
try:
Patrick Mezard
convert: fix parents of last fetched svn revision
r5871 firstcset = None
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 lastonbranch = False
Patrick Mezard
convert: normalize paths sent to svn get_log (issue 1219)
r6850 stream = self._getlog([self.module], from_revnum, to_revnum)
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 try:
for entry in stream:
paths, revnum, author, date, message = entry
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 if revnum < self.startrev:
lastonbranch = True
break
Francis Barber
Fix subversion convert not detecting empty changesets....
r8172 if not paths:
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('revision %d has no entries\n' % revnum)
Patrick Mezard
convert: handle svn tree with empty roots (issue2079)
r10618 # If we ever leave the loop on an empty
# revision, do not try to get a parent branch
lastonbranch = lastonbranch or revnum == 0
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 continue
Thomas Arendsen Hein
Removed trailing spaces from everything except test output
r6210 cset, lastonbranch = parselogentry(paths, revnum, author,
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 date, message)
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 if cset:
firstcset = cset
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 if lastonbranch:
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 break
finally:
stream.close()
Patrick Mezard
convert: fix parents of last fetched svn revision
r5871
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 if not lastonbranch and firstcset and not firstcset.parents:
Patrick Mezard
convert: fix parents of last fetched svn revision
r5871 # The first revision of the sequence (the last fetched one)
# has invalid parents if not a branch root. Find the parent
# revision now, if any.
try:
firstrevnum = self.revnum(firstcset.rev)
if firstrevnum > 1:
latest = self.latest(self.module, firstrevnum - 1)
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 if latest:
firstcset.parents.append(latest)
Patrick Mezard
convert: be even more tolerant when detecting svn tags...
r7381 except SvnPathNotFound:
Patrick Mezard
convert: fix parents of last fetched svn revision
r5871 pass
Thomas Arendsen Hein
Replace _ with inst for catching exceptions to not shadow gettext....
r5140 except SubversionException, (inst, num):
Daniel Holth
convert extension: Add SVN converter
r4765 if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
Brodie Rao
cleanup: eradicate long lines
r16683 raise util.Abort(_('svn: branch has no revision %s')
% to_revnum)
Daniel Holth
convert extension: Add SVN converter
r4765 raise
Patrick Mezard
convert: merge sources getmode() into getfile()
r11134 def getfile(self, file, rev):
Daniel Holth
convert extension: Add SVN converter
r4765 # TODO: ra.get_file transmits the whole file instead of diffs.
Patrick Mezard
convert/svn: do not retrieve removed files...
r11127 if file in self.removed:
Mads Kiilerich
convert: use None value for missing files instead of overloading IOError...
r22296 return None, None
Daniel Holth
convert extension: Add SVN converter
r4765 mode = ''
try:
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 new_module, revnum = revsplit(rev)[1:]
Patrick Mezard
convert: fix cross-branches subversion revisions handling...
r5872 if self.module != new_module:
self.module = new_module
Daniel Holth
convert extension: Add SVN converter
r4765 self.reparent(self.module)
Patrick Mezard
convert: work around svn.ra.get_files() not releasing input buffer
r7446 io = StringIO()
Daniel Holth
convert extension: Add SVN converter
r4765 info = svn.ra.get_file(self.ra, file, revnum, io)
Patrick Mezard
convert: work around svn.ra.get_files() not releasing input buffer
r7446 data = io.getvalue()
Mads Kiilerich
fix trivial spelling errors
r17424 # ra.get_file() seems to keep a reference on the input buffer
timeless@mozdev.org
spelling: Explicitly
r17479 # preventing collection. Release it explicitly.
Patrick Mezard
convert: work around svn.ra.get_files() not releasing input buffer
r7446 io.close()
Daniel Holth
convert extension: Add SVN converter
r4765 if isinstance(info, list):
info = info[-1]
mode = ("svn:executable" in info) and 'x' or ''
mode = ("svn:special" in info) and 'l' or mode
except SubversionException, e:
notfound = (svn.core.SVN_ERR_FS_NOT_FOUND,
svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND)
if e.apr_err in notfound: # File not found
Mads Kiilerich
convert: use None value for missing files instead of overloading IOError...
r22296 return None, None
Daniel Holth
convert extension: Add SVN converter
r4765 raise
if mode == 'l':
link_prefix = "link "
if data.startswith(link_prefix):
data = data[len(link_prefix):]
return data, mode
Patrick Mezard
convert/svn: remove useless sort
r11133 def _iterfiles(self, path, revnum):
"""Enumerate all files in path at revnum, recursively."""
Brendan Cully
convert: svn: ensure leading / is removed from paths in _find_children (broken in 2bd996d0aaf8)
r5114 path = path.strip('/')
Daniel Holth
convert extension: Add SVN converter
r4765 pool = Pool()
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599 rpath = '/'.join([self.baseurl, quote(path)]).strip('/')
Matt Mackall
convert/svn: fix long line
r11167 entries = svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool)
Patrick Mezard
convert/svn: fix _iterfiles() output in root dir case (issue2647)...
r13651 if path:
path += '/'
return ((path + p) for p, e in entries.iteritems()
Patrick Mezard
convert/svn: remove useless sort
r11133 if e.kind == svn.core.svn_node_file)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
Patrick Mezard
convert: rename get_entry_from_path() into an svn_source method
r6539 def getrelpath(self, path, module=None):
if module is None:
module = self.module
# Given the repository url of this wc, say
# "http://server/plone/CMFPlone/branches/Plone-2_0-branch"
# extract the "entry" portion (a relative path) from what
Mads Kiilerich
fix trivial spelling errors
r17424 # svn log --xml says, i.e.
Patrick Mezard
convert: rename get_entry_from_path() into an svn_source method
r6539 # "/CMFPlone/branches/Plone-2_0-branch/tests/PloneTestCase.py"
# that is to say "tests/PloneTestCase.py"
if path.startswith(module):
relative = path.rstrip('/')[len(module):]
if relative.startswith('/'):
return relative[1:]
elif relative == '':
return relative
# The path is outside our tracked tree...
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('%r is not under %r, ignoring\n' % (path, module))
Patrick Mezard
convert: rename get_entry_from_path() into an svn_source method
r6539 return None
Patrick Mezard
convert/svn: handle files/links replaced by dirs (issue2166)
r11128 def _checkpath(self, path, revnum, module=None):
if module is not None:
prevmodule = self.reparent('')
path = module + '/' + path
try:
# ra.check_path does not like leading slashes very much, it leads
# to PROPFIND subversion errors
return svn.ra.check_path(self.ra, path.strip('/'), revnum)
finally:
if module is not None:
self.reparent(prevmodule)
Martin Geisler
check-code: find trailing whitespace
r12770
Patrick Mezard
convert: normalize paths sent to svn get_log (issue 1219)
r6850 def _getlog(self, paths, start, end, limit=0, discover_changed_paths=True,
strict_node_history=False):
# Normalize path names, svn >= 1.5 only wants paths relative to
# supplied URL
relpaths = []
for p in paths:
if not p.startswith('/'):
p = self.module + '/' + p
relpaths.append(p.strip('/'))
Brodie Rao
cleanup: eradicate long lines
r16683 args = [self.baseurl, relpaths, start, end, limit,
discover_changed_paths, strict_node_history]
Mads Kiilerich
convert: secret config option for disabling debugsvnlog...
r20420 # undocumented feature: debugsvnlog can be disabled
if not self.ui.configbool('convert', 'svn.debugsvnlog', True):
return directlogstream(*args)
Patrick Mezard
convert: normalize paths sent to svn get_log (issue 1219)
r6850 arg = encodeargs(args)
hgexe = util.hgexecutable()
cmd = '%s debugsvnlog' % util.shellquote(hgexe)
Steve Borho
convert: subversion should use util.quotecommand to wrap args to popen2...
r13190 stdin, stdout = util.popen2(util.quotecommand(cmd))
Patrick Mezard
convert: normalize paths sent to svn get_log (issue 1219)
r6850 stdin.write(arg)
Patrick Mezard
convert/svn: better handling of hg recursive call failure
r10071 try:
stdin.close()
except IOError:
raise util.Abort(_('Mercurial failed to run itself, check'
' hg executable is in PATH'))
Patrick Mezard
convert: normalize paths sent to svn get_log (issue 1219)
r6850 return logstream(stdout)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 pre_revprop_change = '''#!/bin/sh
REPOS="$1"
REV="$2"
USER="$3"
PROPNAME="$4"
ACTION="$5"
if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi
if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-branch" ]; then exit 0; fi
if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-rev" ]; then exit 0; fi
echo "Changing prohibited revision property" >&2
exit 1
'''
class svn_sink(converter_sink, commandline):
commit_re = re.compile(r'Committed revision (\d+).', re.M)
Patrick Mezard
convert/svn: stop using svn bindings when pushing to svn
r13530 uuid_re = re.compile(r'Repository UUID:\s*(\S+)', re.M)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
def prerun(self):
if self.wc:
os.chdir(self.wc)
def postrun(self):
if self.wc:
os.chdir(self.cwd)
def join(self, name):
return os.path.join(self.wc, '.svn', name)
Thomas Arendsen Hein
Removed tabs and trailing whitespace in python files
r5760
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 def revmapfile(self):
return self.join('hg-shamap')
def authorfile(self):
return self.join('hg-authormap')
def __init__(self, ui, path):
Azhagu Selvan SP
convert/svn: abort operation when python bindings are not available...
r13480
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 converter_sink.__init__(self, ui, path)
commandline.__init__(self, ui, 'svn')
self.delete = []
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 self.setexec = []
self.delexec = []
self.copies = []
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 self.wc = None
self.cwd = os.getcwd()
created = False
if os.path.isfile(os.path.join(path, '.svn', 'entries')):
Patrick Mezard
convert/svn: handle non-local svn destination paths (issue3142)...
r17247 self.wc = os.path.realpath(path)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 self.run0('update')
else:
Patrick Mezard
convert/svn: handle non-local svn destination paths (issue3142)...
r17247 if not re.search(r'^(file|http|https|svn|svn\+ssh)\://', path):
path = os.path.realpath(path)
if os.path.isdir(os.path.dirname(path)):
if not os.path.exists(os.path.join(path, 'db', 'fs-type')):
ui.status(_('initializing svn repository %r\n') %
os.path.basename(path))
commandline(ui, 'svnadmin').run0('create', path)
created = path
path = util.normpath(path)
if not path.startswith('/'):
path = '/' + path
path = 'file://' + path
Patrick Mezard
convert: fix svn file:// URL generation under Windows
r5535
Patrick Mezard
convert/svn: handle non-local svn destination paths (issue3142)...
r17247 wcpath = os.path.join(os.getcwd(), os.path.basename(path) + '-wc')
Martin Geisler
convert: write "working copy" instead of "wc"
r10940 ui.status(_('initializing svn working copy %r\n')
% os.path.basename(wcpath))
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 self.run0('checkout', path, wcpath)
self.wc = wcpath
Adrian Buehlmann
move opener from util to scmutil
r13970 self.opener = scmutil.opener(self.wc)
self.wopener = scmutil.opener(self.wc)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 self.childmap = mapfile(ui, self.join('hg-childmap'))
Adrian Buehlmann
rename util.is_exec to isexec
r14273 self.is_exec = util.checkexec(self.wc) and util.isexec or None
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
if created:
hook = os.path.join(created, 'hooks', 'pre-revprop-change')
fp = open(hook, 'w')
fp.write(pre_revprop_change)
fp.close()
Adrian Buehlmann
rename util.set_flags to setflags
r14232 util.setflags(hook, False, True)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
Patrick Mezard
convert/svn: stop using svn bindings when pushing to svn
r13530 output = self.run0('info')
self.uuid = self.uuid_re.search(output).group(1).strip()
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 def wjoin(self, *names):
return os.path.join(self.wc, *names)
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 @propertycache
def manifest(self):
# As of svn 1.7, the "add" command fails when receiving
# already tracked entries, so we have to track and filter them
# ourselves.
m = set()
output = self.run0('ls', recursive=True, xml=True)
doc = xml.dom.minidom.parseString(output)
for e in doc.getElementsByTagName('entry'):
for n in e.childNodes:
if n.nodeType != n.ELEMENT_NODE or n.tagName != 'name':
continue
name = ''.join(c.data for c in n.childNodes
if c.nodeType == c.TEXT_NODE)
# Entries are compared with names coming from
# mercurial, so bytes with undefined encoding. Our
# best bet is to assume they are in local
# encoding. They will be passed to command line calls
# later anyway, so they better be.
m.add(encoding.tolocal(name.encode('utf-8')))
break
return m
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 def putfile(self, filename, flags, data):
if 'l' in flags:
self.wopener.symlink(data, filename)
else:
try:
if os.path.islink(self.wjoin(filename)):
os.unlink(filename)
except OSError:
pass
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 self.wopener.write(filename, data)
Patrick Mezard
convert: force svn:executable when execute-bit is not supported...
r5536
if self.is_exec:
Mads Kiilerich
convert: ignore svn:executable for subversion targets without exec bit support...
r17031 if self.is_exec(self.wjoin(filename)):
if 'x' not in flags:
self.delexec.append(filename)
else:
if 'x' in flags:
self.setexec.append(filename)
util.setflags(self.wjoin(filename), False, 'x' in flags)
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698
def _copyfile(self, source, dest):
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 # SVN's copy command pukes if the destination file exists, but
# our copyfile method expects to record a copy that has
# already occurred. Cross the semantic gap.
wdest = self.wjoin(dest)
Patrick Mezard
convert/svn: fix broken symlink renames in svn sink
r12343 exists = os.path.lexists(wdest)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 if exists:
fd, tempname = tempfile.mkstemp(
prefix='hg-copy-', dir=os.path.dirname(wdest))
os.close(fd)
os.unlink(tempname)
os.rename(wdest, tempname)
try:
self.run0('copy', source, dest)
finally:
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 self.manifest.add(dest)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 if exists:
try:
os.unlink(wdest)
except OSError:
pass
os.rename(tempname, wdest)
def dirs_of(self, files):
Martin Geisler
util: use built-in set and frozenset...
r8150 dirs = set()
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 for f in files:
if os.path.isdir(self.wjoin(f)):
dirs.add(f)
for i in strutil.rfindall(f, '/'):
dirs.add(f[:i])
return dirs
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 def add_dirs(self, files):
Matt Mackall
replace util.sort with sorted built-in...
r8209 add_dirs = [d for d in sorted(self.dirs_of(files))
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 if d not in self.manifest]
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 if add_dirs:
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 self.manifest.update(add_dirs)
Maxim Dounin
convert: add commandline.xargs(), use it in svn_sink class...
r5832 self.xargs(add_dirs, 'add', non_recursive=True, quiet=True)
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 return add_dirs
def add_files(self, files):
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 files = [f for f in files if f not in self.manifest]
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 if files:
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 self.manifest.update(files)
Maxim Dounin
convert: add commandline.xargs(), use it in svn_sink class...
r5832 self.xargs(files, 'add', quiet=True)
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 return files
Thomas Arendsen Hein
Removed tabs and trailing whitespace in python files
r5760
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 def addchild(self, parent, child):
self.childmap[parent] = child
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554 def revid(self, rev):
return u"svn:%s@%s" % (self.uuid, rev)
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 def putcommit(self, files, copies, parents, commit, source, revmap, full):
Patrick Mezard
convert/svn: update svn working copy only when necessary...
r15605 for parent in parents:
try:
return self.revid(self.childmap[parent])
except KeyError:
pass
Patrick Mezard
convert: reintegrate file retrieval code in sinks...
r6716 # Apply changes to working copy
for f, v in files:
Mads Kiilerich
convert: use None value for missing files instead of overloading IOError...
r22296 data, mode = source.getfile(f, v)
if data is None:
Patrick Mezard
convert: reintegrate file retrieval code in sinks...
r6716 self.delete.append(f)
else:
Patrick Mezard
convert: merge sources getmode() into getfile()
r11134 self.putfile(f, mode, data)
Patrick Mezard
convert: reintegrate file retrieval code in sinks...
r6716 if f in copies:
self.copies.append([copies[f], f])
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 if full:
self.delete.extend(sorted(self.manifest.difference(files)))
Patrick Mezard
convert: reintegrate file retrieval code in sinks...
r6716 files = [f[0] for f in files]
Martin Geisler
util: use built-in set and frozenset...
r8150 entries = set(self.delete)
files = frozenset(files)
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 entries.update(self.add_dirs(files.difference(entries)))
if self.copies:
for s, d in self.copies:
self._copyfile(s, d)
self.copies = []
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 if self.delete:
Maxim Dounin
convert: add commandline.xargs(), use it in svn_sink class...
r5832 self.xargs(self.delete, 'delete')
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 for f in self.delete:
self.manifest.remove(f)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 self.delete = []
entries.update(self.add_files(files.difference(entries)))
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 if self.delexec:
Maxim Dounin
convert: add commandline.xargs(), use it in svn_sink class...
r5832 self.xargs(self.delexec, 'propdel', 'svn:executable')
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 self.delexec = []
if self.setexec:
Maxim Dounin
convert: add commandline.xargs(), use it in svn_sink class...
r5832 self.xargs(self.setexec, 'propset', 'svn:executable', '*')
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 self.setexec = []
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 fd, messagefile = tempfile.mkstemp(prefix='hg-convert-')
fp = os.fdopen(fd, 'w')
fp.write(commit.desc)
fp.close()
try:
output = self.run0('commit',
username=util.shortuser(commit.author),
file=messagefile,
Shun-ichi GOTO
convert: svn_sink: workaround of command line size limitation on win32....
r5790 encoding='utf-8')
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 try:
rev = self.commit_re.search(output).group(1)
except AttributeError:
Patrick Mezard
convert/svn: make sink recover gracefully from empty changeset...
r10051 if not files:
return parents[0]
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 self.ui.warn(_('unexpected svn output:\n'))
self.ui.warn(output)
raise util.Abort(_('unable to cope with svn output'))
if commit.rev:
self.run('propset', 'hg:convert-rev', commit.rev,
revprop=True, revision=rev)
if commit.branch and commit.branch != 'default':
self.run('propset', 'hg:convert-branch', commit.branch,
revprop=True, revision=rev)
for parent in parents:
self.addchild(parent, rev)
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554 return self.revid(rev)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 finally:
os.unlink(messagefile)
def puttags(self, tags):
Martin Geisler
convert: less shouting in SVN sink warning
r11779 self.ui.warn(_('writing Subversion tags is not yet implemented\n'))
Daniel J. Lauk
convert: Using --dest-type svn crashed, if the source repo used tags....
r11778 return None, None
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106
Mads Kiilerich
convert: introduce hascommitfrommap sink method...
r21635 def hascommitfrommap(self, rev):
# We trust that revisions referenced in a map still is present
# TODO: implement something better if necessary and feasible
return True
Mads Kiilerich
convert: rename sink hascommit to hascommitforsplicemap...
r21634 def hascommitforsplicemap(self, rev):
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 # This is not correct as one can convert to an existing subversion
# repository and childmap would not list all revisions. Too bad.
if rev in self.childmap:
return True
raise util.Abort(_('splice map revision %s not found in subversion '
Wagner Bruna
convert: fix typos in error messages
r16162 'child map (revision lookups are not implemented)')
Patrick Mezard
convert: use splicemap entries when sorting revisions (issue1748)...
r16106 % rev)