##// END OF EJS Templates
copies: make mergecopies() distinguish between copies on each side...
copies: make mergecopies() distinguish between copies on each side I find it confusing that most of the dicts returned from `mergecopies()` have entries specific to one branch of the merge, but they're still combined into dict. For example, you can't tell if `copy = {"bar": "foo"}` means that "foo" was copied to "bar" on the first branch or the second. It also feels like there are bugs lurking here because we may mistake which side the copy happened on. However, for most of the dicts, it's not possible that there is disagreement. For example, `renamedelete` keeps track of renames that happened on one side of the merge where the other side deleted the file. There can't be a disagreement there (because we record that in the `diverge` dict instead). For regular copies/renames, there can be a disagreement. Let's say file "foo" was copied to "bar" on one branch and file "baz" was copied to "bar" on the other. Beacause we only return one `copy` dict, we end up replacing the `{"bar": "foo"}` entry by `{"bar": "baz"}`. The merge code (`manifestmerge()`) will then decide that that means "both renamed from 'baz'". We should probably treat it as a conflict instead. The next few patches will make `mergecopies()` return two instances of most of the returned copies. That will lead to a bit more code (~40 lines), but I think it makes both `copies.mergecopies()` and `merge.manifestmerge()` clearer. Differential Revision: https://phab.mercurial-scm.org/D7986

File last commit:

r44474:c1ccefb5 default
r44657:6ca9f45b default
Show More
subversion.py
1565 lines | 55.1 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
timeless
convert: subversion use absolute_import
r28408 from __future__ import absolute_import
Daniel Holth
convert extension: Add SVN converter
r4765
timeless
convert: subversion use absolute_import
r28408 import os
import re
Augie Fackler
convert: move import of xml.minidom.dom to its own line for check-code
r19787 import xml.dom.minidom
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205 from mercurial.i18n import _
Gregory Szorc
py3: manually import pycompat.open into files that need it...
r43355 from mercurial.pycompat import open
timeless
convert: subversion use absolute_import
r28408 from mercurial import (
encoding,
error,
Pulkit Goyal
py3: use pycompat.getcwd() instead of os.getcwd()...
r30519 pycompat,
timeless
convert: subversion use absolute_import
r28408 util,
Pierre-Yves David
vfs: use 'vfs' module directly in 'hgext.convert'...
r31246 vfs as vfsmod,
timeless
convert: subversion use absolute_import
r28408 )
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 from mercurial.utils import (
dateutil,
Yuya Nishihara
procutil: bulk-replace function calls to point to new module
r37138 procutil,
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 stringutil,
)
Daniel Holth
convert extension: Add SVN converter
r4765
timeless
convert: subversion use absolute_import
r28408 from . import common
Pulkit Goyal
py3: conditionalize cPickle import by adding in util...
r29324 pickle = util.pickle
timeless
pycompat: switch to util.stringio for py3 compat
r28861 stringio = util.stringio
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 propertycache = util.propertycache
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 urlerr = util.urlerr
urlreq = util.urlreq
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511
timeless
convert: subversion use absolute_import
r28408 commandline = common.commandline
commit = common.commit
converter_sink = common.converter_sink
converter_source = common.converter_source
decodeargs = common.decodeargs
encodeargs = common.encodeargs
makedatetimestamp = common.makedatetimestamp
mapfile = common.mapfile
MissingTool = common.MissingTool
NoRepo = common.NoRepo
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.
Brendan Cully
convert: activate subversion engine...
r4766 try:
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
FUJIWARA Katsunori
convert: make subversion import transport locally...
r28459 from . import transport
Ronny Pfannschmidt
convert: hide svn deprecation warnings
r8221 import warnings
Augie Fackler
formatting: blacken the codebase...
r43346
warnings.filterwarnings(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'ignore', module=b'svn.core', category=DeprecationWarning
Augie Fackler
formatting: blacken the codebase...
r43346 )
svn.core.SubversionException # trigger import to catch error
Ronny Pfannschmidt
convert: hide svn deprecation warnings
r8221
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
Augie Fackler
formatting: blacken the codebase...
r43346
Patrick Mezard
convert: be even more tolerant when detecting svn tags...
r7381 class SvnPathNotFound(Exception):
pass
Augie Fackler
formatting: blacken the codebase...
r43346
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).
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> revsplit(b'svn:a2147622-4a9f-4db4-a8d3-13562ff547b2'
... b'/proj%20B/mytrunk/mytrunk@1')
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 ('a2147622-4a9f-4db4-a8d3-13562ff547b2', '/proj%20B/mytrunk/mytrunk', 1)
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> revsplit(b'svn:8af66a51-67f5-4354-b62c-98d67cc7be1d@1')
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 ('', '', 1)
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> revsplit(b'@7')
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 ('', '', 7)
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> revsplit(b'7')
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 ('', '', 0)
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> revsplit(b'bad')
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 ('', '', 0)
"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 parts = rev.rsplit(b'@', 1)
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 revnum = 0
if len(parts) > 1:
revnum = int(parts[1])
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 parts = parts[0].split(b'/', 1)
uuid = b''
mod = b''
if len(parts) > 1 and parts[0].startswith(b'svn:'):
Mads Kiilerich
convert: make subversion revsplit more stable when meeting revisions without @...
r20419 uuid = parts[0][4:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 mod = b'/' + 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
Augie Fackler
formatting: blacken the codebase...
r43346
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.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return urlreq.quote(s, b"!$&'()*+,-./:=@_~")
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599
Augie Fackler
formatting: blacken the codebase...
r43346
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))
FUJIWARA Katsunori
convert: fix relative import of stdlib module in subversion...
r28460 except svn.core.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))
Jun Wu
codemod: use pycompat.iswindows...
r34646 if pycompat.iswindows:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 path = b'/' + 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)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 path = b'file://%s' % quote(path)
Patrick Mezard
convert/svn: fix URL quoting issue with svn 1.7...
r15599 return svn.core.svn_path_canonicalize(path)
Brendan Cully
convert: urlify svn repos if necessary....
r5008
Augie Fackler
formatting: blacken the codebase...
r43346
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
Augie Fackler
formatting: blacken the codebase...
r43346
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
Augie Fackler
formatting: blacken the codebase...
r43346
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
Augie Fackler
formatting: blacken the codebase...
r43346
Patrick Mezard
convert: replace fork with subprocess call.
r5127 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:
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 for k, v in pycompat.iteritems(orig_paths):
Mads Kiilerich
convert: fix svn crash when svn.ra.get_log calls back with orig_paths=None...
r20057 paths[k] = changedpath(v)
Augie Fackler
formatting: blacken the codebase...
r43346 pickle.dump((paths, revnum, author, date, message), fp, protocol)
Thomas Arendsen Hein
Remove trailing spaces, fix indentation
r5143
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)
Augie Fackler
formatting: blacken the codebase...
r43346 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)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except Exception as inst:
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 pickle.dump(stringutil.forcebytestr(inst), fp, protocol)
Patrick Mezard
convert: replace fork with subprocess call.
r5127 else:
pickle.dump(None, fp, protocol)
Sascha Nemecek
convert: avoid closing ui.fout in subversion code (issue5807)...
r36529 fp.flush()
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
Augie Fackler
formatting: blacken the codebase...
r43346
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:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'debugsvnlog could not load Subversion python bindings')
Augie Fackler
formatting: blacken the codebase...
r43346 )
Mads Kiilerich
convert: check for failed svn import in debugsvnlog and abort cleanly...
r17053
Yuya Nishihara
convert: have debugsvnlog obtain standard streams from ui...
r30261 args = decodeargs(ui.fin.read())
get_log_child(ui.fout, *args)
Thomas Arendsen Hein
Move debugsvnlog to subversion module.
r5139
Augie Fackler
formatting: blacken the codebase...
r43346
Benoit Boissinot
use new style classes
r8778 class logstream(object):
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 """Interruptible revision log iterator."""
Augie Fackler
formatting: blacken the codebase...
r43346
Patrick Mezard
convert: make svn revision iterator interruptible
r5873 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:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Mercurial failed to run itself, check'
b' hg executable is in PATH'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"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
Augie Fackler
formatting: blacken the codebase...
r43346
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."""
Augie Fackler
formatting: blacken the codebase...
r43346 def __init__(
self,
url,
paths,
start,
end,
limit=0,
discover_changed_paths=True,
strict_node_history=False,
):
Mads Kiilerich
convert: secret config option for disabling debugsvnlog...
r20420 def receiver(orig_paths, revnum, author, date, message, pool):
paths = {}
if orig_paths is not None:
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 for k, v in pycompat.iteritems(orig_paths):
Mads Kiilerich
convert: secret config option for disabling debugsvnlog...
r20420 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)
Augie Fackler
formatting: blacken the codebase...
r43346 svn.ra.get_log(
t.ra,
paths,
start,
end,
limit,
discover_changed_paths,
strict_node_history,
receiver,
)
Mads Kiilerich
convert: secret config option for disabling debugsvnlog...
r20420
def close(self):
pass
Augie Fackler
convert: Improved svn source detection.
r8074
Augie Fackler
formatting: blacken the codebase...
r43346
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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for x in (b'locks', b'hooks', b'format', b'db'):
Augie Fackler
convert: Improved svn source detection.
r8074 if not os.path.exists(os.path.join(path, x)):
return False
return True
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
convert: Improved svn source detection.
r8074 # 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:
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 opener = urlreq.buildopener()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rsp = opener.open(b'%s://%s/!svn/ver/0/.svn' % (proto, path), b'rb')
Matt Mackall
many, many trivial check-code fixups
r10282 data = rsp.read()
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 except urlerr.httperror as 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
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'svn: cannot probe remote repository, assume it could '
b'be a subversion repository. Use --source-type if you '
b'know better.\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
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:
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 # Could be urlerr.urlerror if the URL is invalid or anything else.
Patrick Mezard
convert/svn: delegate to svn bindings if HTTP probe fails...
r9829 return False
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b'<m:human-readable errcode="160013">' in data
Augie Fackler
convert: Improved svn source detection.
r8074
Augie Fackler
formatting: blacken the codebase...
r43346
protomap = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'http': httpcheck,
b'https': httpcheck,
b'file': filecheck,
Augie Fackler
formatting: blacken the codebase...
r43346 }
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 proto, path = url.split(b'://', 1)
if proto == b'file':
Augie Fackler
formatting: blacken the codebase...
r43346 if (
pycompat.iswindows
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 and path[:1] == b'/'
Augie Fackler
formatting: blacken the codebase...
r43346 and path[1:2].isalpha()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 and path[2:6].lower() == b'%3a/'
Augie Fackler
formatting: blacken the codebase...
r43346 ):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 path = path[:2] + b':/' + path[6:]
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 path = urlreq.url2pathname(path)
Edouard Gomez
convert: default to file protocol when no :// found for svn repo url...
r8764 except ValueError:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 proto = b'file'
Edouard Gomez
convert: default to file protocol when no :// found for svn repo url...
r8764 path = os.path.abspath(url)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if proto == b'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
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 while b'/' 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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 path = path.rsplit(b'/', 1)[0]
Augie Fackler
convert: Improved svn source detection.
r8074 return False
Augie Fackler
formatting: blacken the codebase...
r43346
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):
Matt Harbison
convert: save an indicator of the repo type for sources and sinks...
r35168 def __init__(self, ui, repotype, url, revs=None):
super(svn_source, self).__init__(ui, repotype, url, revs=revs)
Brendan Cully
convert: call superclass init from engine init functions
r4807
Augie Fackler
formatting: blacken the codebase...
r43346 if not (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 url.startswith(b'svn://')
or url.startswith(b'svn+ssh://')
Augie Fackler
formatting: blacken the codebase...
r43346 or (
os.path.exists(url)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 and os.path.exists(os.path.join(url, b'.svn'))
Augie Fackler
formatting: blacken the codebase...
r43346 )
or issvnurl(ui, url)
):
raise NoRepo(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"%s does not look like a Subversion repository") % url
Augie Fackler
formatting: blacken the codebase...
r43346 )
Azhagu Selvan SP
convert/svn: abort operation when python bindings are not available...
r13480 if svn is None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise MissingTool(_(b'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):
Augie Fackler
formatting: blacken the codebase...
r43346 raise MissingTool(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Subversion python bindings %d.%d found, '
b'1.4 or later required'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% version
)
Patrick Mezard
convert: improve reporting of invalid svn bindings
r7447 except AttributeError:
Augie Fackler
formatting: blacken the codebase...
r43346 raise MissingTool(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Subversion python bindings are too old, 1.4 '
b'or later required'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
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.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 at = url.rfind(b'@')
Bryan O'Sullivan
convert/subversion.py: str.rsplit is not available in Python 2.3
r4927 if at >= 0:
Augie Fackler
formatting: blacken the codebase...
r43346 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)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.encoding = b'UTF-8' # Subversion is always nominal UTF-8
Daniel Holth
convert extension: Add SVN converter
r4765 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.
Augie Fackler
formatting: blacken the codebase...
r43346 self.module = urlreq.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)
FUJIWARA Katsunori
convert: fix relative import of stdlib module in subversion...
r28460 except svn.core.SubversionException:
Matt Mackall
ui: print_exc() -> traceback()
r8206 ui.traceback()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 svnversion = b'%d.%d.%d' % (
Augie Fackler
formatting: blacken the codebase...
r43346 svn.core.SVN_VER_MAJOR,
svn.core.SVN_VER_MINOR,
svn.core.SVN_VER_MICRO,
)
raise NoRepo(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"%s does not look like a Subversion repository "
b"to libsvn version %s"
Augie Fackler
formatting: blacken the codebase...
r43346 )
% (self.url, svnversion)
)
Daniel Holth
convert extension: Add SVN converter
r4765
Durham Goode
convert: add support for specifying multiple revs...
r25748 if revs:
if len(revs) > 1:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'subversion source does not support '
b'specifying multiple revisions'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Thomas Arendsen Hein
raise util.Abort again if specified revision is not an integer....
r5145 try:
Durham Goode
convert: add support for specifying multiple revs...
r25748 latest = int(revs[0])
Thomas Arendsen Hein
raise util.Abort again if specified revision is not an integer....
r5145 except ValueError:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'svn: revision %s is not an integer') % revs[0]
Augie Fackler
formatting: blacken the codebase...
r43346 )
Thomas Arendsen Hein
raise util.Abort again if specified revision is not an integer....
r5145
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 trunkcfg = self.ui.config(b'convert', b'svn.trunk')
Augie Fackler
convert: register missed subversion config items...
r34891 if trunkcfg is None:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 trunkcfg = b'trunk'
self.trunkname = trunkcfg.strip(b'/')
self.startrev = self.ui.config(b'convert', b'svn.startrev')
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 try:
self.startrev = int(self.startrev)
if self.startrev < 0:
self.startrev = 0
except ValueError:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'svn: start revision %s is not an integer') % self.startrev
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(
_(b'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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if os.path.exists(os.path.join(url, b'.svn/entries')):
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554 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 = {}
Augie Fackler
py3: use default dict iterator instead of iterkeys...
r36313 for revid in revmap:
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:
Augie Fackler
formatting: blacken the codebase...
r43346 svn.client.ls(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.url.rstrip(b'/') + b'/' + quote(path),
Augie Fackler
formatting: blacken the codebase...
r43346 optrev,
False,
self.ctx,
)
Kirill Smelkov
convert: svn -- fix 'exists'...
r5461 return True
FUJIWARA Katsunori
convert: fix relative import of stdlib module in subversion...
r28460 except svn.core.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):
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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cfgpath = self.ui.config(b'convert', b'svn.' + name)
if cfgpath is not None and cfgpath.strip() == b'':
Patrick Mezard
convert: allow svn trunk/branches/tags detection to be skipped...
r6172 return None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 path = (cfgpath or name).strip(b'/')
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 if not self.exists(path, rev):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if self.module.endswith(path) and name == b'trunk':
Pavel Boldin
convert.svn: branch name which equals trunk means `default' branch (issue2653)...
r13494 # we are converting from inside this directory
return None
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 if cfgpath:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'expected %s to be at %r, but not found')
Augie Fackler
formatting: blacken the codebase...
r43346 % (name, path)
)
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 return None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.note(_(b'found %s at %r\n') % (name, path))
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854 return path
Brendan Cully
convert: svn: add helper function for optrevs
r5117 rev = optrev(self.last_changed)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 oldmodule = b''
trunk = getcfgpath(b'trunk', rev)
self.tags = getcfgpath(b'tags', rev)
branches = getcfgpath(b'branches', rev)
Edouard Gomez
convert: separate trunk detection from branch layout detection...
r5854
# If the project has a trunk or branches, we will extract heads
# from them. We keep the project root otherwise.
if trunk:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 oldmodule = self.module or b''
self.module += b'/' + 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:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'no revision found in module %s') % self.module
Augie Fackler
formatting: blacken the codebase...
r43346 )
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.tags = b'%s/%s' % (oldmodule, (self.tags or b'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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rpath = self.url.strip(b'/')
Augie Fackler
formatting: blacken the codebase...
r43346 branchnames = svn.client.ls(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rpath + b'/' + quote(branches), rev, False, self.ctx
Augie Fackler
formatting: blacken the codebase...
r43346 )
Mads Kiilerich
convert: process subversion branch in a sorted order
r18374 for branch in sorted(branchnames):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 module = b'%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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.note(_(b'ignoring empty branch %s\n') % branch)
Patrick Mezard
convert: prevent svn branches to leave the root module tree
r5957 continue
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.note(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'found branch %s at %d\n')
% (branch, self.revnum(brevid))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
convert: fix svn_source.latest()
r5955 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:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'svn: start revision is not supported '
b'with more than one branch'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173 revnum = self.revnum(self.heads[0])
if revnum < self.startrev:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'svn: no revision found after start revision %d')
Augie Fackler
formatting: blacken the codebase...
r43346 % self.startrev
)
Patrick Mezard
convert: add shallow, single branch svn conversions via svn.startrev
r6173
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)
Augie Fackler
formatting: blacken the codebase...
r43346 entries = svn.client.ls(
self.baseurl + quote(module), optrev(revnum), True, self.ctx
)
files = [
n
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 for n, e in pycompat.iteritems(entries)
Augie Fackler
formatting: blacken the codebase...
r43346 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]
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 return (files, copies, set())
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 def checkrevformat(self, revstr, mapname=b'splicemap'):
Ben Goswami
splicemap: improve error handling when source is subversion (issue2084)...
r19122 """ fails if revision format does not match the correct format"""
Augie Fackler
formatting: blacken the codebase...
r43346 if not re.match(
r'svn:[0-9a-f]{8,8}-[0-9a-f]{4,4}-'
r'[0-9a-f]{4,4}-[0-9a-f]{4,4}-[0-9a-f]'
Matt Harbison
cleanup: drop redundant character escapes outside of `[]`...
r44474 r'{12,12}(.*)@[0-9]+$',
Augie Fackler
formatting: blacken the codebase...
r43346 revstr,
):
raise error.Abort(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'%s entry %s is not a valid revision identifier')
Augie Fackler
formatting: blacken the codebase...
r43346 % (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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return int(self.head.rsplit(b'@', 1)[1]) - self.startrev
Augie Fackler
convert: enable deterministic conversion progress bar for svn...
r22414
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 = []
Augie Fackler
formatting: blacken the codebase...
r43346 copies = [
(e.copyfrom_path, e.copyfrom_rev, p)
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 for p, e in pycompat.iteritems(origpaths)
Augie Fackler
formatting: blacken the codebase...
r43346 if e.copyfrom_path
]
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 # 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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not dest.startswith(tagspath + b'/'):
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 continue
for tag in pendings:
if tag[0].startswith(dest):
Augie Fackler
formatting: blacken the codebase...
r43346 tagpath = source + tag[0][len(dest) :]
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 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.
Augie Fackler
formatting: blacken the codebase...
r43346 addeds = dict(
(p, e.copyfrom_path)
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 for p, e in pycompat.iteritems(origpaths)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if e.action == b'A' and e.copyfrom_path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 badroots = set()
for destroot in addeds:
for source, sourcerev, dest in pendings:
Augie Fackler
formatting: blacken the codebase...
r43346 if not dest.startswith(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 destroot + b'/'
) or source.startswith(addeds[destroot] + b'/'):
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 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:
Augie Fackler
formatting: blacken the codebase...
r43346 pendings = [
p
for p in pendings
if p[2] != badroot
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 and not p[2].startswith(badroot + b'/')
Augie Fackler
formatting: blacken the codebase...
r43346 ]
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tagname = dest.split(b'/')[-1]
Aaron Digulla
convert/svn: close gettags() log stream (issue2196)
r11195 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:
Augie Fackler
formatting: blacken the codebase...
r43346 self.convertfp = open(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 os.path.join(self.wc, b'.svn', b'hg-shamap'), b'ab'
Augie Fackler
formatting: blacken the codebase...
r43346 )
self.convertfp.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 util.tonativeeol(b'%s %d\n' % (destrev, self.revnum(rev)))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Bryan O'Sullivan
convert: tell the source repository when a rev has been converted...
r5554 self.convertfp.flush()
Brendan Cully
convert: move some code into common init function
r4810 def revid(self, revnum, module=None):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b'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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return int(rev.split(b'@')[-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 """
Augie Fackler
formatting: blacken the codebase...
r43346
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:
Augie Fackler
formatting: blacken the codebase...
r43346 if not path.startswith(p) or not paths[p].copyfrom_path:
Patrick Mezard
convert/svn: refactor svn_source.latest() with a nested function...
r16465 continue
Augie Fackler
formatting: blacken the codebase...
r43346 newpath = paths[p].copyfrom_path + path[len(p) :]
self.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"branch renamed from %s to %s at %d\n"
Augie Fackler
formatting: blacken the codebase...
r43346 % (path, newpath, revnum)
)
Patrick Mezard
convert/svn: refactor svn_source.latest() with a nested function...
r16465 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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(b'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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prevmodule = self.reparent(b'')
dirent = svn.ra.stat(self.ra, path.strip(b'/'), stop)
Patrick Mezard
convert: restore previous svn transport parent correctly
r6847 self.reparent(prevmodule)
FUJIWARA Katsunori
convert: fix relative import of stdlib module in subversion...
r28460 except svn.core.SubversionException:
Brendan Cully
convert: svn: add function to get the latest revision touching a path...
r4789 dirent = None
if not dirent:
Augie Fackler
formatting: blacken the codebase...
r43346 raise SvnPathNotFound(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s not found up to revision %d') % (path, stop)
Augie Fackler
formatting: blacken the codebase...
r43346 )
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(b'ignoring empty branch %r\n' % realpath)
Patrick Mezard
convert/svn: do not try converting empty head revisions (issue3347)...
r16466 return None
Patrick Mezard
convert/svn: refactor svn_source.latest() with a nested function...
r16465 if not realpath.startswith(self.rootmodule):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(b'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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prevmodule = b''
self.ui.debug(b"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
Augie Fackler
formatting: blacken the codebase...
r43346 progress = self.ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'scanning paths'), unit=_(b'paths'), total=len(paths)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
convert/svn: report path discovery progress...
r11137 for i, (path, ent) in enumerate(paths):
Martin von Zweigbergk
convert: use progress helper...
r38425 progress.update(i, item=path)
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
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"copied to %s from %s@%s\n"
Augie Fackler
formatting: blacken the codebase...
r43346 % (entrypath, copyfrom_path, ent.copyfrom_rev)
)
Patrick Mezard
convert/svn: remove confusing unicode variable
r8885 copies[self.recode(entrypath)] = self.recode(copyfrom_path)
Augie Fackler
formatting: blacken the codebase...
r43346 elif kind == 0: # gone, but had better be a deleted *file*
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(b"gone from %s\n" % ent.copyfrom_rev)
Patrick Mezard
convert/svn: extract revsplit() in a function
r13690 pmodule, prevnum = revsplit(parents[0])[1:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 parentpath = pmodule + b"/" + 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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 oroot = parentpath.strip(b'/')
nroot = path.strip(b'/')
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)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 childpath = self.getrelpath(b"/" + 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:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'unknown path in revision %d: %s\n' % (revnum, path)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martin Geisler
check-code: find trailing whitespace
r12770 elif kind == svn.core.svn_node_dir:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if ent.action == b'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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if ent.action == b'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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 childpath = self.getrelpath(b"/" + childpath)
Patrick Mezard
convert/svn: fix changed files list upon directory replacements...
r13052 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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 childpath = self.getrelpath(b"/" + childpath)
Patrick Mezard
convert/svn: list files explicitely, stop checking their type...
r11132 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
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"mark %s came from %s:%d\n"
Augie Fackler
formatting: blacken the codebase...
r43346 % (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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 childpath = self.getrelpath(b"/" + childpath, pmodule)
Patrick Mezard
convert/svn: list files explicitely, stop checking their type...
r11132 if not childpath:
Patrick Mezard
convert: more cleanup in svn directory copy handling
r6542 continue
Augie Fackler
formatting: blacken the codebase...
r43346 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
Martin von Zweigbergk
convert: use progress helper...
r38425 progress.complete()
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.
"""
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"parsing revision %d (%d changes)\n"
% (revnum, len(orig_paths))
Augie Fackler
formatting: blacken the codebase...
r43346 )
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
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 orig_paths = sorted(pycompat.iteritems(orig_paths))
Augie Fackler
formatting: blacken the codebase...
r43346 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
Augie Fackler
formatting: blacken the codebase...
r43346 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(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'found parent of branch %s at %d: %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (self.module, prevnum, prevmodule)
)
Brendan Cully
convert: svn: hoist up branch creation check
r5119 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(b"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'
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 date = dateutil.parsedate(
date[:19] + b" UTC", [b"%Y-%m-%dT%H:%M:%S"]
)
if self.ui.configbool(b'convert', b'localtimezone'):
Julian Cowley
convert: add config option to use the local time zone...
r17974 date = makedatetimestamp(date[0])
Daniel Holth
convert extension: Add SVN converter
r4765
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if message:
log = self.recode(message)
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 log = b''
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306
if author:
author = self.recode(author)
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 author = b''
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306
Brendan Cully
convert: svn: pull up path to file expansion code into separate function....
r5120 try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 branch = self.module.split(b"/")[-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
Augie Fackler
formatting: blacken the codebase...
r43346 cset = commit(
author=author,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 date=dateutil.datestr(date, b'%Y-%m-%d %H:%M:%S %1%2'),
Augie Fackler
formatting: blacken the codebase...
r43346 desc=log,
parents=parents,
branch=branch,
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
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.note(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'fetching revision log for "%s" from %d to %d\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(b'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
Augie Fackler
formatting: blacken the codebase...
r43346 cset, lastonbranch = parselogentry(
paths, revnum, author, 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
FUJIWARA Katsunori
convert: fix relative import of stdlib module in subversion...
r28460 except svn.core.SubversionException as xxx_todo_changeme:
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 (inst, num) = xxx_todo_changeme.args
Daniel Holth
convert extension: Add SVN converter
r4765 if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'svn: branch has no revision %s') % to_revnum
Augie Fackler
formatting: blacken the codebase...
r43346 )
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 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)
timeless
pycompat: switch to util.stringio for py3 compat
r28861 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]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 mode = (b"svn:executable" in info) and b'x' or b''
mode = (b"svn:special" in info) and b'l' or mode
FUJIWARA Katsunori
convert: fix relative import of stdlib module in subversion...
r28460 except svn.core.SubversionException as e:
Augie Fackler
formatting: blacken the codebase...
r43346 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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if mode == b'l':
link_prefix = b"link "
Daniel Holth
convert extension: Add SVN converter
r4765 if data.startswith(link_prefix):
Augie Fackler
formatting: blacken the codebase...
r43346 data = data[len(link_prefix) :]
Daniel Holth
convert extension: Add SVN converter
r4765 return data, mode
Patrick Mezard
convert/svn: remove useless sort
r11133 def _iterfiles(self, path, revnum):
"""Enumerate all files in path at revnum, recursively."""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 path = path.strip(b'/')
FUJIWARA Katsunori
convert: fix relative import of stdlib module in subversion...
r28460 pool = svn.core.Pool()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rpath = b'/'.join([self.baseurl, quote(path)]).strip(b'/')
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 path += b'/'
Augie Fackler
formatting: blacken the codebase...
r43346 return (
(path + p)
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 for p, e in pycompat.iteritems(entries)
Augie Fackler
formatting: blacken the codebase...
r43346 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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 relative = path.rstrip(b'/')[len(module) :]
if relative.startswith(b'/'):
Patrick Mezard
convert: rename get_entry_from_path() into an svn_source method
r6539 return relative[1:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif relative == b'':
Patrick Mezard
convert: rename get_entry_from_path() into an svn_source method
r6539 return relative
# The path is outside our tracked tree...
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.debug(b'%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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prevmodule = self.reparent(b'')
path = module + b'/' + path
Patrick Mezard
convert/svn: handle files/links replaced by dirs (issue2166)
r11128 try:
# ra.check_path does not like leading slashes very much, it leads
# to PROPFIND subversion errors
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return svn.ra.check_path(self.ra, path.strip(b'/'), revnum)
Patrick Mezard
convert/svn: handle files/links replaced by dirs (issue2166)
r11128 finally:
if module is not None:
self.reparent(prevmodule)
Martin Geisler
check-code: find trailing whitespace
r12770
Augie Fackler
formatting: blacken the codebase...
r43346 def _getlog(
self,
paths,
start,
end,
limit=0,
discover_changed_paths=True,
strict_node_history=False,
):
Patrick Mezard
convert: normalize paths sent to svn get_log (issue 1219)
r6850 # Normalize path names, svn >= 1.5 only wants paths relative to
# supplied URL
relpaths = []
for p in paths:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not p.startswith(b'/'):
p = self.module + b'/' + p
relpaths.append(p.strip(b'/'))
Augie Fackler
formatting: blacken the codebase...
r43346 args = [
self.baseurl,
relpaths,
start,
end,
limit,
discover_changed_paths,
strict_node_history,
]
timeless
convert/svn: quiet check-config
r27314 # developer config: convert.svn.debugsvnlog
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not self.ui.configbool(b'convert', b'svn.debugsvnlog'):
Mads Kiilerich
convert: secret config option for disabling debugsvnlog...
r20420 return directlogstream(*args)
Patrick Mezard
convert: normalize paths sent to svn get_log (issue 1219)
r6850 arg = encodeargs(args)
Yuya Nishihara
procutil: bulk-replace function calls to point to new module
r37138 hgexe = procutil.hgexecutable()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd = b'%s debugsvnlog' % procutil.shellquote(hgexe)
Yuya Nishihara
procutil: bulk-replace function calls to point to new module
r37138 stdin, stdout = procutil.popen2(procutil.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:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Mercurial failed to run itself, check'
b' hg executable is in PATH'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Patrick Mezard
convert: normalize paths sent to svn get_log (issue 1219)
r6850 return logstream(stdout)
Augie Fackler
formatting: blacken the codebase...
r43346
Pulkit Goyal
py3: add b'' prefixes in hgext/convert/subversion.py...
r38079 pre_revprop_change = b'''#!/bin/sh
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
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
'''
Augie Fackler
formatting: blacken the codebase...
r43346
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 class svn_sink(converter_sink, commandline):
Pulkit Goyal
py3: add b'' prefixes in hgext/convert/subversion.py...
r38079 commit_re = re.compile(br'Committed revision (\d+).', re.M)
uuid_re = re.compile(br'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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return os.path.join(self.wc, b'.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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self.join(b'hg-shamap')
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
def authorfile(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self.join(b'hg-authormap')
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
Matt Harbison
convert: save an indicator of the repo type for sources and sinks...
r35168 def __init__(self, ui, repotype, path):
Azhagu Selvan SP
convert/svn: abort operation when python bindings are not available...
r13480
Matt Harbison
convert: save an indicator of the repo type for sources and sinks...
r35168 converter_sink.__init__(self, ui, repotype, path)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 commandline.__init__(self, ui, b'svn')
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 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
Matt Harbison
py3: rename pycompat.getcwd() to encoding.getcwd() (API)...
r39843 self.cwd = encoding.getcwd()
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
created = False
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if os.path.isfile(os.path.join(path, b'.svn', b'entries')):
Patrick Mezard
convert/svn: handle non-local svn destination paths (issue3142)...
r17247 self.wc = os.path.realpath(path)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.run0(b'update')
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 else:
Matt Harbison
cleanup: drop redundant character escapes outside of `[]`...
r44474 if not re.search(br'^(file|http|https|svn|svn\+ssh)://', path):
Patrick Mezard
convert/svn: handle non-local svn destination paths (issue3142)...
r17247 path = os.path.realpath(path)
if os.path.isdir(os.path.dirname(path)):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not os.path.exists(
os.path.join(path, b'db', b'fs-type')
):
Augie Fackler
formatting: blacken the codebase...
r43346 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"initializing svn repository '%s'\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % os.path.basename(path)
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 commandline(ui, b'svnadmin').run0(b'create', path)
Patrick Mezard
convert/svn: handle non-local svn destination paths (issue3142)...
r17247 created = path
path = util.normpath(path)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not path.startswith(b'/'):
path = b'/' + path
path = b'file://' + path
Patrick Mezard
convert: fix svn file:// URL generation under Windows
r5535
Augie Fackler
formatting: blacken the codebase...
r43346 wcpath = os.path.join(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 encoding.getcwd(), os.path.basename(path) + b'-wc'
Augie Fackler
formatting: blacken the codebase...
r43346 )
ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"initializing svn working copy '%s'\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % os.path.basename(wcpath)
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.run0(b'checkout', path, wcpath)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
self.wc = wcpath
Pierre-Yves David
vfs: use 'vfs' module directly in 'hgext.convert'...
r31246 self.opener = vfsmod.vfs(self.wc)
self.wopener = vfsmod.vfs(self.wc)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.childmap = mapfile(ui, self.join(b'hg-childmap'))
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if util.checkexec(self.wc):
self.is_exec = util.isexec
else:
self.is_exec = None
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513
if created:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 hook = os.path.join(created, b'hooks', b'pre-revprop-change')
fp = open(hook, b'wb')
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 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
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output = self.run0(b'info')
Patrick Mezard
convert/svn: stop using svn bindings when pushing to svn
r13530 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()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output = self.run0(b'ls', recursive=True, xml=True)
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 doc = xml.dom.minidom.parseString(output)
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 for e in doc.getElementsByTagName('entry'):
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 for n in e.childNodes:
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 if n.nodeType != n.ELEMENT_NODE or n.tagName != 'name':
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 continue
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 name = ''.join(
Augie Fackler
formatting: blacken the codebase...
r43346 c.data for c in n.childNodes if c.nodeType == c.TEXT_NODE
)
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 # 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.
Yuya Nishihara
encoding: factor out unicode variants of from/tolocal()...
r31447 m.add(encoding.unitolocal(name))
Patrick Mezard
convert/svn: make svn sink work with svn 1.7...
r16511 break
return m
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 def putfile(self, filename, flags, data):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'l' in flags:
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 self.wopener.symlink(data, filename)
else:
try:
if os.path.islink(self.wjoin(filename)):
os.unlink(filename)
except OSError:
pass
Nikita Slyusarev
convert: handle exec bit removal while converting to svn...
r41766
if self.is_exec:
# We need to check executability of the file before the change,
# because `vfs.write` is able to reset exec bit.
wasexec = False
if os.path.exists(self.wjoin(filename)):
wasexec = self.is_exec(self.wjoin(filename))
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:
Nikita Slyusarev
convert: handle exec bit removal while converting to svn...
r41766 if wasexec:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'x' not in flags:
Mads Kiilerich
convert: ignore svn:executable for subversion targets without exec bit support...
r17031 self.delexec.append(filename)
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'x' in flags:
Mads Kiilerich
convert: ignore svn:executable for subversion targets without exec bit support...
r17031 self.setexec.append(filename)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 util.setflags(self.wjoin(filename), False, b'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:
Yuya Nishihara
py3: wrap tempfile.mkstemp() to use bytes path...
r38182 fd, tempname = pycompat.mkstemp(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prefix=b'hg-copy-', dir=os.path.dirname(wdest)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 os.close(fd)
os.unlink(tempname)
os.rename(wdest, tempname)
try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.run0(b'copy', source, dest)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 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)
Yuya Nishihara
convert: inline strutil.rfindall()...
r30605 i = len(f)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for i in iter(lambda: f.rfind(b'/', 0, i), -1):
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 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):
Augie Fackler
formatting: blacken the codebase...
r43346 add_dirs = [
d for d in sorted(self.dirs_of(files)) 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)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.xargs(add_dirs, b'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)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.xargs(files, b'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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b"svn:%s@%s" % (self.uuid, rev)
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698
Augie Fackler
formatting: blacken the codebase...
r43346 def putcommit(
self, files, copies, parents, commit, source, revmap, full, cleanp2
):
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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.xargs(self.delete, b'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:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.xargs(self.delexec, b'propdel', b'svn:executable')
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 self.delexec = []
if self.setexec:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.xargs(self.setexec, b'propset', b'svn:executable', b'*')
Maxim Dounin
convert: svn-sink: copy and set properties after adding dirs/files...
r5698 self.setexec = []
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fd, messagefile = pycompat.mkstemp(prefix=b'hg-convert-')
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 fp = os.fdopen(fd, 'wb')
Yuya Nishihara
convert: fix line ending of mapfile and commit.desc file...
r36166 fp.write(util.tonativeeol(commit.desc))
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 fp.close()
try:
Augie Fackler
formatting: blacken the codebase...
r43346 output = self.run0(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'commit',
Augie Fackler
formatting: blacken the codebase...
r43346 username=stringutil.shortuser(commit.author),
file=messagefile,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 encoding=b'utf-8',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 try:
rev = self.commit_re.search(output).group(1)
except AttributeError:
Nikita Slyusarev
convert: handle empty intial commits while converting to svn...
r41765 if not files:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return parents[0] if parents else b'None'
self.ui.warn(_(b'unexpected svn output:\n'))
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 self.ui.warn(output)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'unable to cope with svn output'))
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 if commit.rev:
Augie Fackler
formatting: blacken the codebase...
r43346 self.run(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'propset',
b'hg:convert-rev',
Augie Fackler
formatting: blacken the codebase...
r43346 commit.rev,
revprop=True,
revision=rev,
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if commit.branch and commit.branch != b'default':
Augie Fackler
formatting: blacken the codebase...
r43346 self.run(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'propset',
b'hg:convert-branch',
Augie Fackler
formatting: blacken the codebase...
r43346 commit.branch,
revprop=True,
revision=rev,
)
Bryan O'Sullivan
convert: add support for Subversion as a sink
r5513 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):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.warn(_(b'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
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'splice map revision %s not found in subversion '
b'child map (revision lookups are not implemented)'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% rev
)