hgext/convert/subversion.py
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
Tue, 12 Nov 2013 16:23:52 +0900
changeset 20084 a3378a1b0a05
parent 20057 d54467c1a198
child 20373 e8203629371b
permissions -rw-r--r--
transaction: unlink target file via vfs Before this patch, unlink target file is once opened before unlinking, because "opener" before vfs migration doesn't have "unlink()" function. This patch uses "vfs.unlink()" instead of "open()" and "fp.name".
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
     1
# Subversion 1.4/1.5 Python API backend
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
     2
#
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
     3
# Copyright(C) 2007 Daniel Holth et al
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
     4
19787
87f07f70f227 convert: move import of xml.minidom.dom to its own line for check-code
Augie Fackler <raf@durin42.com>
parents: 19468
diff changeset
     5
import os, re, sys, tempfile, urllib, urllib2
87f07f70f227 convert: move import of xml.minidom.dom to its own line for check-code
Augie Fackler <raf@durin42.com>
parents: 19468
diff changeset
     6
import xml.dom.minidom
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
     7
import cPickle as pickle
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
     8
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13690
diff changeset
     9
from mercurial import strutil, scmutil, util, encoding
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
    10
from mercurial.i18n import _
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    11
16511
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
    12
propertycache = util.propertycache
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
    13
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    14
# Subversion stuff. Works best with very recent Python SVN bindings
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    15
# e.g. SVN 1.5 or backports. Thanks to the bzr folks for enhancing
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    16
# these bindings.
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    17
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    18
from cStringIO import StringIO
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    19
7447
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
    20
from common import NoRepo, MissingTool, commit, encodeargs, decodeargs
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
    21
from common import commandline, converter_source, converter_sink, mapfile
17974
337d728e644f convert: add config option to use the local time zone
Julian Cowley <julian@lava.net>
parents: 17537
diff changeset
    22
from common import makedatetimestamp
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    23
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    24
try:
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    25
    from svn.core import SubversionException, Pool
5010
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
    26
    import svn
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
    27
    import svn.client
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    28
    import svn.core
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    29
    import svn.ra
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    30
    import svn.delta
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    31
    import transport
8221
f35b933044cc convert: hide svn deprecation warnings
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8219
diff changeset
    32
    import warnings
f35b933044cc convert: hide svn deprecation warnings
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8219
diff changeset
    33
    warnings.filterwarnings('ignore',
f35b933044cc convert: hide svn deprecation warnings
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8219
diff changeset
    34
            module='svn.core',
f35b933044cc convert: hide svn deprecation warnings
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8219
diff changeset
    35
            category=DeprecationWarning)
f35b933044cc convert: hide svn deprecation warnings
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 8219
diff changeset
    36
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    37
except ImportError:
13480
69418d4525d1 convert/svn: abort operation when python bindings are not available
Azhagu Selvan SP <tamizhgeek@gmail.com>
parents: 13190
diff changeset
    38
    svn = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    39
7381
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
    40
class SvnPathNotFound(Exception):
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
    41
    pass
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
    42
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
    43
def revsplit(rev):
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
    44
    """Parse a revision string and return (uuid, path, revnum)."""
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
    45
    url, revnum = rev.rsplit('@', 1)
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
    46
    parts = url.split('/', 1)
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
    47
    mod = ''
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
    48
    if len(parts) > 1:
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
    49
        mod = '/' + parts[1]
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
    50
    return parts[0][4:], mod, int(revnum)
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
    51
15599
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    52
def quote(s):
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    53
    # As of svn 1.7, many svn calls expect "canonical" paths. In
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    54
    # theory, we should call svn.core.*canonicalize() on all paths
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    55
    # before passing them to the API.  Instead, we assume the base url
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    56
    # is canonical and copy the behaviour of svn URL encoding function
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    57
    # so we can extend it safely with new components. The "safe"
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    58
    # characters were taken from the "svn_uri__char_validity" table in
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    59
    # libsvn_subr/path.c.
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    60
    return urllib.quote(s, "!$&'()*+,-./:=@_~")
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    61
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
    62
def geturl(path):
5010
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
    63
    try:
5020
780051cca03c convert svn: canonicalize path before calling url_from_path.
Brendan Cully <brendan@kublai.com>
parents: 5010
diff changeset
    64
        return svn.client.url_from_path(svn.core.svn_path_canonicalize(path))
5010
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
    65
    except SubversionException:
15599
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    66
        # svn.client.url_from_path() fails with local repositories
5010
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
    67
        pass
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
    68
    if os.path.isdir(path):
5793
68f5bf9aa582 convert: Accept local path on win32.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5790
diff changeset
    69
        path = os.path.normpath(os.path.abspath(path))
68f5bf9aa582 convert: Accept local path on win32.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5790
diff changeset
    70
        if os.name == 'nt':
5842
111ed8c871bf Use util.normpath() instead of direct path string operation.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5841
diff changeset
    71
            path = '/' + util.normpath(path)
8886
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
    72
        # Module URL is later compared with the repository URL returned
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
    73
        # by svn API, which is UTF-8.
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
    74
        path = encoding.tolocal(path)
15599
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    75
        path = 'file://%s' % quote(path)
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
    76
    return svn.core.svn_path_canonicalize(path)
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
    77
5117
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    78
def optrev(number):
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    79
    optrev = svn.core.svn_opt_revision_t()
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    80
    optrev.kind = svn.core.svn_opt_revision_number
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    81
    optrev.value.number = number
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    82
    return optrev
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    83
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
    84
class changedpath(object):
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
    85
    def __init__(self, p):
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
    86
        self.copyfrom_path = p.copyfrom_path
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
    87
        self.copyfrom_rev = p.copyfrom_rev
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
    88
        self.action = p.action
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
    89
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16514
diff changeset
    90
def get_log_child(fp, url, paths, start, end, limit=0,
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16514
diff changeset
    91
                  discover_changed_paths=True, strict_node_history=False):
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    92
    protocol = -1
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    93
    def receiver(orig_paths, revnum, author, date, message, pool):
20057
d54467c1a198 convert: fix svn crash when svn.ra.get_log calls back with orig_paths=None
Mads Kiilerich <madski@unity3d.com>
parents: 19787
diff changeset
    94
        paths = {}
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    95
        if orig_paths is not None:
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    96
            for k, v in orig_paths.iteritems():
20057
d54467c1a198 convert: fix svn crash when svn.ra.get_log calls back with orig_paths=None
Mads Kiilerich <madski@unity3d.com>
parents: 19787
diff changeset
    97
                paths[k] = changedpath(v)
d54467c1a198 convert: fix svn crash when svn.ra.get_log calls back with orig_paths=None
Mads Kiilerich <madski@unity3d.com>
parents: 19787
diff changeset
    98
        pickle.dump((paths, revnum, author, date, message),
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5141
diff changeset
    99
                    fp, protocol)
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5141
diff changeset
   100
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   101
    try:
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   102
        # Use an ra of our own so that our parent can consume
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   103
        # our results without confusing the server.
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   104
        t = transport.SvnRaTransport(url=url)
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   105
        svn.ra.get_log(t.ra, paths, start, end, limit,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   106
                       discover_changed_paths,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   107
                       strict_node_history,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   108
                       receiver)
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   109
    except IOError:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   110
        # Caller may interrupt the iteration
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   111
        pickle.dump(None, fp, protocol)
15750
03d04296cfab convert: improve exception reporting for SVN logstream
Matt Mackall <mpm@selenic.com>
parents: 15599
diff changeset
   112
    except Exception, inst:
03d04296cfab convert: improve exception reporting for SVN logstream
Matt Mackall <mpm@selenic.com>
parents: 15599
diff changeset
   113
        pickle.dump(str(inst), fp, protocol)
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   114
    else:
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   115
        pickle.dump(None, fp, protocol)
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   116
    fp.close()
6397
e1402cf5e08a convert: avoid svn log retrieval process cleanup
Patrick Mezard <pmezard@gmail.com>
parents: 6281
diff changeset
   117
    # With large history, cleanup process goes crazy and suddenly
e1402cf5e08a convert: avoid svn log retrieval process cleanup
Patrick Mezard <pmezard@gmail.com>
parents: 6281
diff changeset
   118
    # consumes *huge* amount of memory. The output file being closed,
e1402cf5e08a convert: avoid svn log retrieval process cleanup
Patrick Mezard <pmezard@gmail.com>
parents: 6281
diff changeset
   119
    # there is no need for clean termination.
e1402cf5e08a convert: avoid svn log retrieval process cleanup
Patrick Mezard <pmezard@gmail.com>
parents: 6281
diff changeset
   120
    os._exit(0)
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
   121
5139
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   122
def debugsvnlog(ui, **opts):
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   123
    """Fetch SVN log in a subprocess and channel them back to parent to
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   124
    avoid memory collection issues.
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   125
    """
17053
0e4171fdb9d4 convert: check for failed svn import in debugsvnlog and abort cleanly
Mads Kiilerich <mads@kiilerich.com>
parents: 17052
diff changeset
   126
    if svn is None:
0e4171fdb9d4 convert: check for failed svn import in debugsvnlog and abort cleanly
Mads Kiilerich <mads@kiilerich.com>
parents: 17052
diff changeset
   127
        raise util.Abort(_('debugsvnlog could not load Subversion python '
0e4171fdb9d4 convert: check for failed svn import in debugsvnlog and abort cleanly
Mads Kiilerich <mads@kiilerich.com>
parents: 17052
diff changeset
   128
                           'bindings'))
0e4171fdb9d4 convert: check for failed svn import in debugsvnlog and abort cleanly
Mads Kiilerich <mads@kiilerich.com>
parents: 17052
diff changeset
   129
14233
659f34b833b9 rename util.set_binary to setbinary
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   130
    util.setbinary(sys.stdin)
659f34b833b9 rename util.set_binary to setbinary
Adrian Buehlmann <adrian@cadifra.com>
parents: 14232
diff changeset
   131
    util.setbinary(sys.stdout)
5139
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   132
    args = decodeargs(sys.stdin.read())
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   133
    get_log_child(sys.stdout, *args)
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   134
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8764
diff changeset
   135
class logstream(object):
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   136
    """Interruptible revision log iterator."""
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   137
    def __init__(self, stdout):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   138
        self._stdout = stdout
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   139
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   140
    def __iter__(self):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   141
        while True:
9587
d80a251baf9a convert/svn: better error when hg cannot call itself (issue1838)
Patrick Mezard <pmezard@gmail.com>
parents: 9521
diff changeset
   142
            try:
d80a251baf9a convert/svn: better error when hg cannot call itself (issue1838)
Patrick Mezard <pmezard@gmail.com>
parents: 9521
diff changeset
   143
                entry = pickle.load(self._stdout)
d80a251baf9a convert/svn: better error when hg cannot call itself (issue1838)
Patrick Mezard <pmezard@gmail.com>
parents: 9521
diff changeset
   144
            except EOFError:
d80a251baf9a convert/svn: better error when hg cannot call itself (issue1838)
Patrick Mezard <pmezard@gmail.com>
parents: 9521
diff changeset
   145
                raise util.Abort(_('Mercurial failed to run itself, check'
d80a251baf9a convert/svn: better error when hg cannot call itself (issue1838)
Patrick Mezard <pmezard@gmail.com>
parents: 9521
diff changeset
   146
                                   ' hg executable is in PATH'))
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   147
            try:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   148
                orig_paths, revnum, author, date, message = entry
16688
cfb6682961b8 cleanup: replace naked excepts with more specific ones
Brodie Rao <brodie@sf.io>
parents: 16687
diff changeset
   149
            except (TypeError, ValueError):
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   150
                if entry is None:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   151
                    break
15750
03d04296cfab convert: improve exception reporting for SVN logstream
Matt Mackall <mpm@selenic.com>
parents: 15599
diff changeset
   152
                raise util.Abort(_("log stream exception '%s'") % entry)
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   153
            yield entry
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   154
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   155
    def close(self):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   156
        if self._stdout:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   157
            self._stdout.close()
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   158
            self._stdout = None
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   159
8074
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   160
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   161
# Check to see if the given path is a local Subversion repo. Verify this by
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   162
# looking for several svn-specific files and directories in the given
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   163
# directory.
9829
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   164
def filecheck(ui, path, proto):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   165
    for x in ('locks', 'hooks', 'format', 'db'):
8074
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   166
        if not os.path.exists(os.path.join(path, x)):
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   167
            return False
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   168
    return True
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   169
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   170
# Check to see if a given path is the root of an svn repo over http. We verify
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   171
# this by requesting a version-controlled URL we know can't exist and looking
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   172
# for the svn-specific "not found" XML.
9829
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   173
def httpcheck(ui, path, proto):
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   174
    try:
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   175
        opener = urllib2.build_opener()
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   176
        rsp = opener.open('%s://%s/!svn/ver/0/.svn' % (proto, path))
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   177
        data = rsp.read()
9829
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   178
    except urllib2.HTTPError, inst:
9838
2e51cc30fc30 convert/svn: fix HTTP detection bug introduced by 1b2516a547d4
Patrick Mezard <pmezard@gmail.com>
parents: 9829
diff changeset
   179
        if inst.code != 404:
2e51cc30fc30 convert/svn: fix HTTP detection bug introduced by 1b2516a547d4
Patrick Mezard <pmezard@gmail.com>
parents: 9829
diff changeset
   180
            # Except for 404 we cannot know for sure this is not an svn repo
9860
9c43089b372a convert/svn: fix warning when repo detection failed
Patrick Mezard <pmezard@gmail.com>
parents: 9838
diff changeset
   181
            ui.warn(_('svn: cannot probe remote repository, assume it could '
9c43089b372a convert/svn: fix warning when repo detection failed
Patrick Mezard <pmezard@gmail.com>
parents: 9838
diff changeset
   182
                      'be a subversion repository. Use --source-type if you '
9c43089b372a convert/svn: fix warning when repo detection failed
Patrick Mezard <pmezard@gmail.com>
parents: 9838
diff changeset
   183
                      'know better.\n'))
9838
2e51cc30fc30 convert/svn: fix HTTP detection bug introduced by 1b2516a547d4
Patrick Mezard <pmezard@gmail.com>
parents: 9829
diff changeset
   184
            return True
2e51cc30fc30 convert/svn: fix HTTP detection bug introduced by 1b2516a547d4
Patrick Mezard <pmezard@gmail.com>
parents: 9829
diff changeset
   185
        data = inst.fp.read()
16689
f366d4c2ff34 cleanup: replace naked excepts with except Exception: ...
Brodie Rao <brodie@sf.io>
parents: 16688
diff changeset
   186
    except Exception:
9829
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   187
        # Could be urllib2.URLError if the URL is invalid or anything else.
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   188
        return False
9838
2e51cc30fc30 convert/svn: fix HTTP detection bug introduced by 1b2516a547d4
Patrick Mezard <pmezard@gmail.com>
parents: 9829
diff changeset
   189
    return '<m:human-readable errcode="160013">' in data
8074
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   190
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   191
protomap = {'http': httpcheck,
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   192
            'https': httpcheck,
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   193
            'file': filecheck,
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   194
            }
9829
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   195
def issvnurl(ui, url):
8764
46b5b4301fcc convert: default to file protocol when no :// found for svn repo url
Edouard Gomez <ed.gomez@free.fr>
parents: 8693
diff changeset
   196
    try:
46b5b4301fcc convert: default to file protocol when no :// found for svn repo url
Edouard Gomez <ed.gomez@free.fr>
parents: 8693
diff changeset
   197
        proto, path = url.split('://', 1)
9521
e3ce0c30798b Fix issue 1782 don't do url2pathname conversion for urls
Grauw <laurens.hg@grauw.nl>
parents: 9168
diff changeset
   198
        if proto == 'file':
17052
1bd18c415eec convert: accept Subversion 'file:///c%3A/svnrepo' syntax on Windows
Mads Kiilerich <mads@kiilerich.com>
parents: 17031
diff changeset
   199
            if (os.name == 'nt' and path[:1] == '/' and path[1:2].isalpha()
1bd18c415eec convert: accept Subversion 'file:///c%3A/svnrepo' syntax on Windows
Mads Kiilerich <mads@kiilerich.com>
parents: 17031
diff changeset
   200
                and path[2:6].lower() == '%3a/'):
1bd18c415eec convert: accept Subversion 'file:///c%3A/svnrepo' syntax on Windows
Mads Kiilerich <mads@kiilerich.com>
parents: 17031
diff changeset
   201
                path = path[:2] + ':/' + path[6:]
9521
e3ce0c30798b Fix issue 1782 don't do url2pathname conversion for urls
Grauw <laurens.hg@grauw.nl>
parents: 9168
diff changeset
   202
            path = urllib.url2pathname(path)
8764
46b5b4301fcc convert: default to file protocol when no :// found for svn repo url
Edouard Gomez <ed.gomez@free.fr>
parents: 8693
diff changeset
   203
    except ValueError:
46b5b4301fcc convert: default to file protocol when no :// found for svn repo url
Edouard Gomez <ed.gomez@free.fr>
parents: 8693
diff changeset
   204
        proto = 'file'
46b5b4301fcc convert: default to file protocol when no :// found for svn repo url
Edouard Gomez <ed.gomez@free.fr>
parents: 8693
diff changeset
   205
        path = os.path.abspath(url)
9521
e3ce0c30798b Fix issue 1782 don't do url2pathname conversion for urls
Grauw <laurens.hg@grauw.nl>
parents: 9168
diff changeset
   206
    if proto == 'file':
16067
467a85ced564 i18n: use util.pconvert() instead of 'str.replace()' for problematic encoding
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15970
diff changeset
   207
        path = util.pconvert(path)
10885
9e4d120e3c32 convert/subversion: fix default URL checker prototype
Patrick Mezard <pmezard@gmail.com>
parents: 10618
diff changeset
   208
    check = protomap.get(proto, lambda *args: False)
8074
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   209
    while '/' in path:
9829
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   210
        if check(ui, path, proto):
8074
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   211
            return True
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   212
        path = path.rsplit('/', 1)[0]
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   213
    return False
fc78313cba53 convert: Improved svn source detection.
Augie Fackler <durin42@gmail.com>
parents: 7973
diff changeset
   214
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   215
# SVN conversion code stolen from bzr-svn and tailor
5876
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   216
#
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   217
# Subversion looks like a versioned filesystem, branches structures
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   218
# are defined by conventions and not enforced by the tool. First,
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   219
# we define the potential branches (modules) as "trunk" and "branches"
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   220
# children directories. Revisions are then identified by their
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   221
# module and revision number (and a repository identifier).
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   222
#
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   223
# The revision graph is really a tree (or a forest). By default, a
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   224
# revision parent is the previous revision in the same module. If the
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   225
# module directory is copied/moved from another module then the
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   226
# revision is the module root and its parent the source revision in
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   227
# the parent module. A revision has at most one parent.
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   228
#
5438
6fa5258be3d4 convert: rename convert_svn to svn_source
Bryan O'Sullivan <bos@serpentine.com>
parents: 5437
diff changeset
   229
class svn_source(converter_source):
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   230
    def __init__(self, ui, url, rev=None):
5438
6fa5258be3d4 convert: rename convert_svn to svn_source
Bryan O'Sullivan <bos@serpentine.com>
parents: 5437
diff changeset
   231
        super(svn_source, self).__init__(ui, url, rev=rev)
4807
15a3cbfc6568 convert: call superclass init from engine init functions
Brendan Cully <brendan@kublai.com>
parents: 4799
diff changeset
   232
7973
db3a68fd9387 convert: attempt to check repo type before checking for tool
Matt Mackall <mpm@selenic.com>
parents: 7875
diff changeset
   233
        if not (url.startswith('svn://') or url.startswith('svn+ssh://') or
db3a68fd9387 convert: attempt to check repo type before checking for tool
Matt Mackall <mpm@selenic.com>
parents: 7875
diff changeset
   234
                (os.path.exists(url) and
db3a68fd9387 convert: attempt to check repo type before checking for tool
Matt Mackall <mpm@selenic.com>
parents: 7875
diff changeset
   235
                 os.path.exists(os.path.join(url, '.svn'))) or
9829
1b2516a547d4 convert/svn: delegate to svn bindings if HTTP probe fails
Patrick Mezard <pmezard@gmail.com>
parents: 9819
diff changeset
   236
                issvnurl(ui, url)):
10939
9f6731b03906 convert: mark strings for translation
Martin Geisler <mg@lazybytes.net>
parents: 10938
diff changeset
   237
            raise NoRepo(_("%s does not look like a Subversion repository")
9f6731b03906 convert: mark strings for translation
Martin Geisler <mg@lazybytes.net>
parents: 10938
diff changeset
   238
                         % url)
13480
69418d4525d1 convert/svn: abort operation when python bindings are not available
Azhagu Selvan SP <tamizhgeek@gmail.com>
parents: 13190
diff changeset
   239
        if svn is None:
16925
eaf6a6d7f015 convert: lowercase status and abort messages
Martin Geisler <mg@aragost.com>
parents: 16689
diff changeset
   240
            raise MissingTool(_('could not load Subversion python bindings'))
7447
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
   241
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
   242
        try:
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
   243
            version = svn.core.SVN_VER_MAJOR, svn.core.SVN_VER_MINOR
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
   244
            if version < (1, 4):
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
   245
                raise MissingTool(_('Subversion python bindings %d.%d found, '
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
   246
                                    '1.4 or later required') % version)
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
   247
        except AttributeError:
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
   248
            raise MissingTool(_('Subversion python bindings are too old, 1.4 '
4fd92687f331 convert: improve reporting of invalid svn bindings
Patrick Mezard <pmezard@gmail.com>
parents: 7446
diff changeset
   249
                                'or later required'))
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   250
4813
1fcdf2fe3d7c convert: svn: use revmap to parse only new revisions in incremental conversions
Brendan Cully <brendan@kublai.com>
parents: 4811
diff changeset
   251
        self.lastrevs = {}
1fcdf2fe3d7c convert: svn: use revmap to parse only new revisions in incremental conversions
Brendan Cully <brendan@kublai.com>
parents: 4811
diff changeset
   252
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   253
        latest = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   254
        try:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   255
            # Support file://path@rev syntax. Useful e.g. to convert
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   256
            # deleted branches.
4927
5e89b0dafce5 convert/subversion.py: str.rsplit is not available in Python 2.3
Bryan O'Sullivan <bos@serpentine.com>
parents: 4925
diff changeset
   257
            at = url.rfind('@')
5e89b0dafce5 convert/subversion.py: str.rsplit is not available in Python 2.3
Bryan O'Sullivan <bos@serpentine.com>
parents: 4925
diff changeset
   258
            if at >= 0:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   259
                latest = int(url[at + 1:])
4927
5e89b0dafce5 convert/subversion.py: str.rsplit is not available in Python 2.3
Bryan O'Sullivan <bos@serpentine.com>
parents: 4925
diff changeset
   260
                url = url[:at]
7874
d812029cda85 cleanup: drop variables for unused return values
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7857
diff changeset
   261
        except ValueError:
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   262
            pass
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
   263
        self.url = geturl(url)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   264
        self.encoding = 'UTF-8' # Subversion is always nominal UTF-8
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   265
        try:
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
   266
            self.transport = transport.SvnRaTransport(url=self.url)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   267
            self.ra = self.transport.ra
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
   268
            self.ctx = self.transport.client
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
   269
            self.baseurl = svn.ra.get_repos_root(self.ra)
6538
05dff77bfbd9 convert: fix subpaths detection in svn source
Patrick Mezard <pmezard@gmail.com>
parents: 6493
diff changeset
   270
            # Module is either empty or a repository path starting with
05dff77bfbd9 convert: fix subpaths detection in svn source
Patrick Mezard <pmezard@gmail.com>
parents: 6493
diff changeset
   271
            # a slash and not ending with a slash.
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
   272
            self.module = urllib.unquote(self.url[len(self.baseurl):])
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   273
            self.prevmodule = None
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   274
            self.rootmodule = self.module
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   275
            self.commits = {}
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   276
            self.paths = {}
8886
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
   277
            self.uuid = svn.ra.get_uuid(self.ra)
7875
553aa0cbeab6 cleanup: drop unused assignments
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   278
        except SubversionException:
8206
cce63ef1045b ui: print_exc() -> traceback()
Matt Mackall <mpm@selenic.com>
parents: 8172
diff changeset
   279
            ui.traceback()
10939
9f6731b03906 convert: mark strings for translation
Martin Geisler <mg@lazybytes.net>
parents: 10938
diff changeset
   280
            raise NoRepo(_("%s does not look like a Subversion repository")
10938
02d6149a480b convert: write "repository" instead of "repo"
Martin Geisler <mg@lazybytes.net>
parents: 10885
diff changeset
   281
                         % self.url)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   282
5145
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   283
        if rev:
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   284
            try:
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   285
                latest = int(rev)
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   286
            except ValueError:
6956
12472a240398 i18n: mark strings for translation in convert extension
Martin Geisler <mg@daimi.au.dk>
parents: 6884
diff changeset
   287
                raise util.Abort(_('svn: revision %s is not an integer') % rev)
5145
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   288
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16514
diff changeset
   289
        self.trunkname = self.ui.config('convert', 'svn.trunk',
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16514
diff changeset
   290
                                        'trunk').strip('/')
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   291
        self.startrev = self.ui.config('convert', 'svn.startrev', default=0)
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   292
        try:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   293
            self.startrev = int(self.startrev)
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   294
            if self.startrev < 0:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   295
                self.startrev = 0
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   296
        except ValueError:
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
   297
            raise util.Abort(_('svn: start revision %s is not an integer')
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   298
                             % self.startrev)
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   299
14152
00121103546a convert: handle invalid subversion source paths
Mads Kiilerich <mads@kiilerich.com>
parents: 13970
diff changeset
   300
        try:
00121103546a convert: handle invalid subversion source paths
Mads Kiilerich <mads@kiilerich.com>
parents: 13970
diff changeset
   301
            self.head = self.latest(self.module, latest)
00121103546a convert: handle invalid subversion source paths
Mads Kiilerich <mads@kiilerich.com>
parents: 13970
diff changeset
   302
        except SvnPathNotFound:
00121103546a convert: handle invalid subversion source paths
Mads Kiilerich <mads@kiilerich.com>
parents: 13970
diff changeset
   303
            self.head = None
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   304
        if not self.head:
8886
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
   305
            raise util.Abort(_('no revision found in module %s')
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
   306
                             % self.module)
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
   307
        self.last_changed = self.revnum(self.head)
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
   308
5382
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   309
        self._changescache = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   310
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   311
        if os.path.exists(os.path.join(url, '.svn/entries')):
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   312
            self.wc = url
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   313
        else:
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   314
            self.wc = None
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   315
        self.convertfp = None
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   316
5510
11d7908a3ea8 convert: abstract map files into a class
Bryan O'Sullivan <bos@serpentine.com>
parents: 5462
diff changeset
   317
    def setrevmap(self, revmap):
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   318
        lastrevs = {}
5511
03bb1296a1c3 convert: iterate
Bryan O'Sullivan <bos@serpentine.com>
parents: 5510
diff changeset
   319
        for revid in revmap.iterkeys():
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   320
            uuid, module, revnum = revsplit(revid)
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   321
            lastrevnum = lastrevs.setdefault(module, revnum)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   322
            if revnum > lastrevnum:
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   323
                lastrevs[module] = revnum
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   324
        self.lastrevs = lastrevs
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   325
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   326
    def exists(self, path, optrev):
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   327
        try:
15599
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
   328
            svn.client.ls(self.url.rstrip('/') + '/' + quote(path),
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   329
                                 optrev, False, self.ctx)
5461
ab4d2e9f3b97 convert: svn -- fix 'exists'
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5438
diff changeset
   330
            return True
7875
553aa0cbeab6 cleanup: drop unused assignments
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
   331
        except SubversionException:
5461
ab4d2e9f3b97 convert: svn -- fix 'exists'
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5438
diff changeset
   332
            return False
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   333
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   334
    def getheads(self):
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   335
6491
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
   336
        def isdir(path, revnum):
6848
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
   337
            kind = self._checkpath(path, revnum)
6491
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
   338
            return kind == svn.core.svn_node_dir
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
   339
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   340
        def getcfgpath(name, rev):
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   341
            cfgpath = self.ui.config('convert', 'svn.' + name)
6172
0cd6846e5200 convert: allow svn trunk/branches/tags detection to be skipped
Patrick Mezard <pmezard@gmail.com>
parents: 6053
diff changeset
   342
            if cfgpath is not None and cfgpath.strip() == '':
0cd6846e5200 convert: allow svn trunk/branches/tags detection to be skipped
Patrick Mezard <pmezard@gmail.com>
parents: 6053
diff changeset
   343
                return None
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   344
            path = (cfgpath or name).strip('/')
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   345
            if not self.exists(path, rev):
13494
3178aca36b0f convert.svn: branch name which equals trunk means `default' branch (issue2653)
Pavel Boldin <boldin.pavel@gmail.com>
parents: 13480
diff changeset
   346
                if self.module.endswith(path) and name == 'trunk':
3178aca36b0f convert.svn: branch name which equals trunk means `default' branch (issue2653)
Pavel Boldin <boldin.pavel@gmail.com>
parents: 13480
diff changeset
   347
                    # we are converting from inside this directory
3178aca36b0f convert.svn: branch name which equals trunk means `default' branch (issue2653)
Pavel Boldin <boldin.pavel@gmail.com>
parents: 13480
diff changeset
   348
                    return None
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   349
                if cfgpath:
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   350
                    raise util.Abort(_('expected %s to be at %r, but not found')
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   351
                                 % (name, path))
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   352
                return None
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   353
            self.ui.note(_('found %s at %r\n') % (name, path))
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   354
            return path
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   355
5117
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
   356
        rev = optrev(self.last_changed)
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   357
        oldmodule = ''
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   358
        trunk = getcfgpath('trunk', rev)
6400
c237b27e1350 convert: allow tags detection to be disabled
Patrick Mezard <pmezard@gmail.com>
parents: 6399
diff changeset
   359
        self.tags = getcfgpath('tags', rev)
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   360
        branches = getcfgpath('branches', rev)
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   361
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   362
        # If the project has a trunk or branches, we will extract heads
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   363
        # from them. We keep the project root otherwise.
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   364
        if trunk:
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   365
            oldmodule = self.module or ''
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   366
            self.module += '/' + trunk
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
   367
            self.head = self.latest(self.module, self.last_changed)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   368
            if not self.head:
9312
c5f0825c1dbb kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9169
diff changeset
   369
                raise util.Abort(_('no revision found in module %s')
8886
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
   370
                                 % self.module)
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   371
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   372
        # First head in the list is the module's head
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   373
        self.heads = [self.head]
6400
c237b27e1350 convert: allow tags detection to be disabled
Patrick Mezard <pmezard@gmail.com>
parents: 6399
diff changeset
   374
        if self.tags is not None:
c237b27e1350 convert: allow tags detection to be disabled
Patrick Mezard <pmezard@gmail.com>
parents: 6399
diff changeset
   375
            self.tags = '%s/%s' % (oldmodule , (self.tags or 'tags'))
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   376
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   377
        # Check if branches bring a few more heads to the list
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   378
        if branches:
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   379
            rpath = self.url.strip('/')
15599
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
   380
            branchnames = svn.client.ls(rpath + '/' + quote(branches),
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
   381
                                        rev, False, self.ctx)
18374
942ecb55b1de convert: process subversion branch in a sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 17974
diff changeset
   382
            for branch in sorted(branchnames):
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   383
                module = '%s/%s/%s' % (oldmodule, branches, branch)
6491
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
   384
                if not isdir(module, self.last_changed):
2bdd43246c95 convert: check svn branches are directories
Patrick Mezard <pmezard@gmail.com>
parents: 6400
diff changeset
   385
                    continue
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
   386
                brevid = self.latest(module, self.last_changed)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   387
                if not brevid:
8886
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
   388
                    self.ui.note(_('ignoring empty branch %s\n') % branch)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   389
                    continue
6956
12472a240398 i18n: mark strings for translation in convert extension
Martin Geisler <mg@daimi.au.dk>
parents: 6884
diff changeset
   390
                self.ui.note(_('found branch %s at %d\n') %
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
   391
                             (branch, self.revnum(brevid)))
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
   392
                self.heads.append(brevid)
5462
91a522a69c13 convert: svn -- fix tags handling
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5461
diff changeset
   393
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   394
        if self.startrev and self.heads:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   395
            if len(self.heads) > 1:
8086
89b6450148d0 convert: fix typo
Wagner Bruna <wbruna@yahoo.com>
parents: 7973
diff changeset
   396
                raise util.Abort(_('svn: start revision is not supported '
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   397
                                   'with more than one branch'))
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   398
            revnum = self.revnum(self.heads[0])
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   399
            if revnum < self.startrev:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   400
                raise util.Abort(
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   401
                    _('svn: no revision found after start revision %d')
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   402
                                 % self.startrev)
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   403
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   404
        return self.heads
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   405
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   406
    def getchanges(self, rev):
5382
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   407
        if self._changescache and self._changescache[0] == rev:
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   408
            return self._changescache[1]
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   409
        self._changescache = None
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   410
        (paths, parents) = self.paths[rev]
5956
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
   411
        if parents:
11127
ab575114ddd8 convert/svn: do not retrieve removed files
Patrick Mezard <pmezard@gmail.com>
parents: 11126
diff changeset
   412
            files, self.removed, copies = self.expandpaths(rev, paths, parents)
5956
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
   413
        else:
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
   414
            # Perform a full checkout on roots
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   415
            uuid, module, revnum = revsplit(rev)
15599
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
   416
            entries = svn.client.ls(self.baseurl + quote(module),
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
   417
                                    optrev(revnum), True, self.ctx)
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   418
            files = [n for n, e in entries.iteritems()
5956
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
   419
                     if e.kind == svn.core.svn_node_file]
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
   420
            copies = {}
11127
ab575114ddd8 convert/svn: do not retrieve removed files
Patrick Mezard <pmezard@gmail.com>
parents: 11126
diff changeset
   421
            self.removed = set()
5956
094638b3cbed convert: checkout svn root revisions
Patrick Mezard <pmezard@gmail.com>
parents: 5955
diff changeset
   422
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   423
        files.sort()
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   424
        files = zip(files, [rev] * len(files))
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   425
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   426
        # caller caches the result, so free it here to release memory
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   427
        del self.paths[rev]
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   428
        return (files, copies)
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   429
5382
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   430
    def getchangedfiles(self, rev, i):
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   431
        changes = self.getchanges(rev)
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   432
        self._changescache = (rev, changes)
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   433
        return [f[0] for f in changes[0]]
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   434
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   435
    def getcommit(self, rev):
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   436
        if rev not in self.commits:
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   437
            uuid, module, revnum = revsplit(rev)
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   438
            self.module = module
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   439
            self.reparent(module)
5875
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   440
            # We assume that:
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   441
            # - requests for revisions after "stop" come from the
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   442
            # revision graph backward traversal. Cache all of them
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   443
            # down to stop, they will be used eventually.
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   444
            # - requests for revisions before "stop" come to get
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   445
            # isolated branches parents. Just fetch what is needed.
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   446
            stop = self.lastrevs.get(module, 0)
5875
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   447
            if revnum < stop:
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   448
                stop = revnum + 1
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   449
            self._fetch_revisions(revnum, stop)
15970
9f2ed48f8cda convert: subversion convert abort on revision not found (issue 3205)
Jesus Espino Garcia <jesus.espino@kaleidos.net>
parents: 15751
diff changeset
   450
            if rev not in self.commits:
9f2ed48f8cda convert: subversion convert abort on revision not found (issue 3205)
Jesus Espino Garcia <jesus.espino@kaleidos.net>
parents: 15751
diff changeset
   451
                raise util.Abort(_('svn: revision %s not found') % revnum)
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   452
        commit = self.commits[rev]
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   453
        # caller caches the result, so free it here to release memory
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   454
        del self.commits[rev]
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   455
        return commit
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   456
19122
83973dc1bfe9 splicemap: improve error handling when source is subversion (issue2084)
Ben Goswami <bengoswami@fb.com>
parents: 18374
diff changeset
   457
    def checkrevformat(self, revstr):
83973dc1bfe9 splicemap: improve error handling when source is subversion (issue2084)
Ben Goswami <bengoswami@fb.com>
parents: 18374
diff changeset
   458
        """ fails if revision format does not match the correct format"""
83973dc1bfe9 splicemap: improve error handling when source is subversion (issue2084)
Ben Goswami <bengoswami@fb.com>
parents: 18374
diff changeset
   459
        if not re.match(r'svn:[0-9a-f]{8,8}-[0-9a-f]{4,4}-'
83973dc1bfe9 splicemap: improve error handling when source is subversion (issue2084)
Ben Goswami <bengoswami@fb.com>
parents: 18374
diff changeset
   460
                              '[0-9a-f]{4,4}-[0-9a-f]{4,4}-[0-9a-f]'
83973dc1bfe9 splicemap: improve error handling when source is subversion (issue2084)
Ben Goswami <bengoswami@fb.com>
parents: 18374
diff changeset
   461
                              '{12,12}(.*)\@[0-9]+$',revstr):
83973dc1bfe9 splicemap: improve error handling when source is subversion (issue2084)
Ben Goswami <bengoswami@fb.com>
parents: 18374
diff changeset
   462
            raise util.Abort(_('splicemap entry %s is not a valid revision'
83973dc1bfe9 splicemap: improve error handling when source is subversion (issue2084)
Ben Goswami <bengoswami@fb.com>
parents: 18374
diff changeset
   463
                               ' identifier') % revstr)
83973dc1bfe9 splicemap: improve error handling when source is subversion (issue2084)
Ben Goswami <bengoswami@fb.com>
parents: 18374
diff changeset
   464
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   465
    def gettags(self):
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   466
        tags = {}
6172
0cd6846e5200 convert: allow svn trunk/branches/tags detection to be skipped
Patrick Mezard <pmezard@gmail.com>
parents: 6053
diff changeset
   467
        if self.tags is None:
0cd6846e5200 convert: allow svn trunk/branches/tags detection to be skipped
Patrick Mezard <pmezard@gmail.com>
parents: 6053
diff changeset
   468
            return tags
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
   469
6399
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   470
        # svn tags are just a convention, project branches left in a
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   471
        # 'tags' directory. There is no other relationship than
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   472
        # ancestry, which is expensive to discover and makes them hard
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   473
        # to update incrementally.  Worse, past revisions may be
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   474
        # referenced by tags far away in the future, requiring a deep
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   475
        # history traversal on every calculation.  Current code
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   476
        # performs a single backward traversal, tracking moves within
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   477
        # the tags directory (tag renaming) and recording a new tag
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   478
        # everytime a project is copied from outside the tags
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   479
        # directory. It also lists deleted tags, this behaviour may
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   480
        # change in the future.
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   481
        pendings = []
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   482
        tagspath = self.tags
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   483
        start = svn.ra.get_latest_revnum(self.ra)
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   484
        stream = self._getlog([self.tags], start, self.startrev)
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   485
        try:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   486
            for entry in stream:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   487
                origpaths, revnum, author, date, message = entry
19468
82c512643bed convert: catch empty origpaths in svn gettags (issue3941)
Matt Mackall <mpm@selenic.com>
parents: 19122
diff changeset
   488
                if not origpaths:
82c512643bed convert: catch empty origpaths in svn gettags (issue3941)
Matt Mackall <mpm@selenic.com>
parents: 19122
diff changeset
   489
                    origpaths = []
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   490
                copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p, e
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   491
                          in origpaths.iteritems() if e.copyfrom_path]
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   492
                # Apply moves/copies from more specific to general
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   493
                copies.sort(reverse=True)
6399
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   494
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   495
                srctagspath = tagspath
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   496
                if copies and copies[-1][2] == tagspath:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   497
                    # Track tags directory moves
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   498
                    srctagspath = copies.pop()[0]
6399
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   499
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   500
                for source, sourcerev, dest in copies:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   501
                    if not dest.startswith(tagspath + '/'):
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   502
                        continue
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   503
                    for tag in pendings:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   504
                        if tag[0].startswith(dest):
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   505
                            tagpath = source + tag[0][len(dest):]
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   506
                            tag[:2] = [tagpath, sourcerev]
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   507
                            break
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   508
                    else:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   509
                        pendings.append([source, sourcerev, dest])
8248
d093e57671ea convert/svn: ignore composite tags
Patrick Mezard <pmezard@gmail.com>
parents: 8247
diff changeset
   510
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   511
                # Filter out tags with children coming from different
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   512
                # parts of the repository like:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   513
                # /tags/tag.1 (from /trunk:10)
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   514
                # /tags/tag.1/foo (from /branches/foo:12)
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   515
                # Here/tags/tag.1 discarded as well as its children.
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   516
                # It happens with tools like cvs2svn. Such tags cannot
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   517
                # be represented in mercurial.
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   518
                addeds = dict((p, e.copyfrom_path) for p, e
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   519
                              in origpaths.iteritems()
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   520
                              if e.action == 'A' and e.copyfrom_path)
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   521
                badroots = set()
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   522
                for destroot in addeds:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   523
                    for source, sourcerev, dest in pendings:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   524
                        if (not dest.startswith(destroot + '/')
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   525
                            or source.startswith(addeds[destroot] + '/')):
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   526
                            continue
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   527
                        badroots.add(destroot)
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   528
                        break
8248
d093e57671ea convert/svn: ignore composite tags
Patrick Mezard <pmezard@gmail.com>
parents: 8247
diff changeset
   529
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   530
                for badroot in badroots:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   531
                    pendings = [p for p in pendings if p[2] != badroot
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   532
                                and not p[2].startswith(badroot + '/')]
6399
5efd447a9b8d convert: follow svn tags history (issue953)
Patrick Mezard <pmezard@gmail.com>
parents: 6397
diff changeset
   533
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   534
                # Tell tag renamings from tag creations
15124
8542a9c9f679 convert: rename local variable
Martin Geisler <mg@aragost.com>
parents: 14273
diff changeset
   535
                renamings = []
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   536
                for source, sourcerev, dest in pendings:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   537
                    tagname = dest.split('/')[-1]
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   538
                    if source.startswith(srctagspath):
15124
8542a9c9f679 convert: rename local variable
Martin Geisler <mg@aragost.com>
parents: 14273
diff changeset
   539
                        renamings.append([source, sourcerev, tagname])
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   540
                        continue
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   541
                    if tagname in tags:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   542
                        # Keep the latest tag value
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   543
                        continue
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   544
                    # From revision may be fake, get one with changes
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   545
                    try:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   546
                        tagid = self.latest(source, sourcerev)
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   547
                        if tagid and tagname not in tags:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   548
                            tags[tagname] = tagid
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   549
                    except SvnPathNotFound:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   550
                        # It happens when we are following directories
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   551
                        # we assumed were copied with their parents
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   552
                        # but were really created in the tag
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   553
                        # directory.
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   554
                        pass
15124
8542a9c9f679 convert: rename local variable
Martin Geisler <mg@aragost.com>
parents: 14273
diff changeset
   555
                pendings = renamings
11195
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   556
                tagspath = srctagspath
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   557
        finally:
46bb49134498 convert/svn: close gettags() log stream (issue2196)
Aaron Digulla <digulla@hepe.com>
parents: 11194
diff changeset
   558
            stream.close()
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
   559
        return tags
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   560
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   561
    def converted(self, rev, destrev):
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   562
        if not self.wc:
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   563
            return
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   564
        if self.convertfp is None:
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   565
            self.convertfp = open(os.path.join(self.wc, '.svn', 'hg-shamap'),
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   566
                                  'a')
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   567
        self.convertfp.write('%s %d\n' % (destrev, self.revnum(rev)))
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   568
        self.convertfp.flush()
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   569
4810
c2d529f288a1 convert: move some code into common init function
Brendan Cully <brendan@kublai.com>
parents: 4807
diff changeset
   570
    def revid(self, revnum, module=None):
8886
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
   571
        return 'svn:%s%s@%s' % (self.uuid, module or self.module, revnum)
4774
d305852a5ec8 convert: svn: add revnum() to convert rev to revnum
Brendan Cully <brendan@kublai.com>
parents: 4773
diff changeset
   572
d305852a5ec8 convert: svn: add revnum() to convert rev to revnum
Brendan Cully <brendan@kublai.com>
parents: 4773
diff changeset
   573
    def revnum(self, rev):
d305852a5ec8 convert: svn: add revnum() to convert rev to revnum
Brendan Cully <brendan@kublai.com>
parents: 4773
diff changeset
   574
        return int(rev.split('@')[-1])
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   575
16464
0e1329d905df convert/svn: clarify svn_source.latest() stop arg default value
Patrick Mezard <patrick@mezard.eu>
parents: 16162
diff changeset
   576
    def latest(self, path, stop=None):
0e1329d905df convert/svn: clarify svn_source.latest() stop arg default value
Patrick Mezard <patrick@mezard.eu>
parents: 16162
diff changeset
   577
        """Find the latest revid affecting path, up to stop revision
0e1329d905df convert/svn: clarify svn_source.latest() stop arg default value
Patrick Mezard <patrick@mezard.eu>
parents: 16162
diff changeset
   578
        number. If stop is None, default to repository latest
0e1329d905df convert/svn: clarify svn_source.latest() stop arg default value
Patrick Mezard <patrick@mezard.eu>
parents: 16162
diff changeset
   579
        revision. It may return a revision in a different module,
0e1329d905df convert/svn: clarify svn_source.latest() stop arg default value
Patrick Mezard <patrick@mezard.eu>
parents: 16162
diff changeset
   580
        since a branch may be moved without a change being
0e1329d905df convert/svn: clarify svn_source.latest() stop arg default value
Patrick Mezard <patrick@mezard.eu>
parents: 16162
diff changeset
   581
        reported. Return None if computed module does not belong to
0e1329d905df convert/svn: clarify svn_source.latest() stop arg default value
Patrick Mezard <patrick@mezard.eu>
parents: 16162
diff changeset
   582
        rootmodule subtree.
5955
c4496b7c10ce convert: fix svn_source.latest()
Patrick Mezard <pmezard@gmail.com>
parents: 5921
diff changeset
   583
        """
16466
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   584
        def findchanges(path, start, stop=None):
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   585
            stream = self._getlog([path], start, stop or 1)
16465
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   586
            try:
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   587
                for entry in stream:
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   588
                    paths, revnum, author, date, message = entry
16466
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   589
                    if stop is None and paths:
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   590
                        # We do not know the latest changed revision,
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   591
                        # keep the first one with changed paths.
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   592
                        break
16465
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   593
                    if revnum <= stop:
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   594
                        break
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   595
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   596
                    for p in paths:
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   597
                        if (not path.startswith(p) or
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   598
                            not paths[p].copyfrom_path):
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   599
                            continue
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   600
                        newpath = paths[p].copyfrom_path + path[len(p):]
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   601
                        self.ui.debug("branch renamed from %s to %s at %d\n" %
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   602
                                      (path, newpath, revnum))
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   603
                        path = newpath
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   604
                        break
16466
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   605
                if not paths:
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   606
                    revnum = None
16465
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   607
                return revnum, path
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   608
            finally:
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   609
                stream.close()
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   610
6281
3e5f99b13998 convert: avoid querying log of foreign svn branches
Patrick Mezard <pmezard@gmail.com>
parents: 6214
diff changeset
   611
        if not path.startswith(self.rootmodule):
3e5f99b13998 convert: avoid querying log of foreign svn branches
Patrick Mezard <pmezard@gmail.com>
parents: 6214
diff changeset
   612
            # Requests on foreign branches may be forbidden at server level
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   613
            self.ui.debug('ignoring foreign branch %r\n' % path)
6281
3e5f99b13998 convert: avoid querying log of foreign svn branches
Patrick Mezard <pmezard@gmail.com>
parents: 6214
diff changeset
   614
            return None
3e5f99b13998 convert: avoid querying log of foreign svn branches
Patrick Mezard <pmezard@gmail.com>
parents: 6214
diff changeset
   615
16464
0e1329d905df convert/svn: clarify svn_source.latest() stop arg default value
Patrick Mezard <patrick@mezard.eu>
parents: 16162
diff changeset
   616
        if stop is None:
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   617
            stop = svn.ra.get_latest_revnum(self.ra)
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   618
        try:
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   619
            prevmodule = self.reparent('')
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   620
            dirent = svn.ra.stat(self.ra, path.strip('/'), stop)
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   621
            self.reparent(prevmodule)
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   622
        except SubversionException:
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   623
            dirent = None
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   624
        if not dirent:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   625
            raise SvnPathNotFound(_('%s not found up to revision %d')
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   626
                                  % (path, stop))
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   627
8660
b9ec04eb2aa3 convert/subversion: wrap long lines in comments
Martin Geisler <mg@lazybytes.net>
parents: 8339
diff changeset
   628
        # stat() gives us the previous revision on this line of
b9ec04eb2aa3 convert/subversion: wrap long lines in comments
Martin Geisler <mg@lazybytes.net>
parents: 8339
diff changeset
   629
        # development, but it might be in *another module*. Fetch the
b9ec04eb2aa3 convert/subversion: wrap long lines in comments
Martin Geisler <mg@lazybytes.net>
parents: 8339
diff changeset
   630
        # log and detect renames down to the latest revision.
16465
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   631
        revnum, realpath = findchanges(path, stop, dirent.created_rev)
16466
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   632
        if revnum is None:
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   633
            # Tools like svnsync can create empty revision, when
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   634
            # synchronizing only a subtree for instance. These empty
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   635
            # revisions created_rev still have their original values
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   636
            # despite all changes having disappeared and can be
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   637
            # returned by ra.stat(), at least when stating the root
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   638
            # module. In that case, do not trust created_rev and scan
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   639
            # the whole history.
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   640
            revnum, realpath = findchanges(path, stop)
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   641
            if revnum is None:
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   642
                self.ui.debug('ignoring empty branch %r\n' % realpath)
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   643
                return None
c53a49c345e1 convert/svn: do not try converting empty head revisions (issue3347)
Patrick Mezard <patrick@mezard.eu>
parents: 16465
diff changeset
   644
16465
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   645
        if not realpath.startswith(self.rootmodule):
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   646
            self.ui.debug('ignoring foreign branch %r\n' % realpath)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   647
            return None
16465
ad38b96c88f9 convert/svn: refactor svn_source.latest() with a nested function
Patrick Mezard <patrick@mezard.eu>
parents: 16464
diff changeset
   648
        return self.revid(revnum, realpath)
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   649
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   650
    def reparent(self, module):
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   651
        """Reparent the svn transport and return the previous parent."""
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   652
        if self.prevmodule == module:
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   653
            return module
15599
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
   654
        svnurl = self.baseurl + quote(module)
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   655
        prevmodule = self.prevmodule
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   656
        if prevmodule is None:
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   657
            prevmodule = ''
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   658
        self.ui.debug("reparent to %s\n" % svnurl)
7074
b1a4f67b98d0 convert: properly encode subversion URLs (issue 1224)
Patrick Mezard <pmezard@gmail.com>
parents: 6877
diff changeset
   659
        svn.ra.reparent(self.ra, svnurl)
6847
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   660
        self.prevmodule = module
9d6d1fdb7d72 convert: restore previous svn transport parent correctly
Patrick Mezard <pmezard@gmail.com>
parents: 6553
diff changeset
   661
        return prevmodule
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   662
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   663
    def expandpaths(self, rev, paths, parents):
11127
ab575114ddd8 convert/svn: do not retrieve removed files
Patrick Mezard <pmezard@gmail.com>
parents: 11126
diff changeset
   664
        changed, removed = set(), set()
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   665
        copies = {}
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   666
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   667
        new_module, revnum = revsplit(rev)[1:]
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   668
        if new_module != self.module:
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   669
            self.module = new_module
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   670
            self.reparent(self.module)
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   671
11137
94afe7bc87a9 convert/svn: report path discovery progress
Patrick Mezard <pmezard@gmail.com>
parents: 11134
diff changeset
   672
        for i, (path, ent) in enumerate(paths):
94afe7bc87a9 convert/svn: report path discovery progress
Patrick Mezard <pmezard@gmail.com>
parents: 11134
diff changeset
   673
            self.ui.progress(_('scanning paths'), i, item=path,
94afe7bc87a9 convert/svn: report path discovery progress
Patrick Mezard <pmezard@gmail.com>
parents: 11134
diff changeset
   674
                             total=len(paths))
6539
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   675
            entrypath = self.getrelpath(path)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   676
6848
59c40c60d8d8 convert: remove leading slash from ra.check_path inputs (issue 1236)
Patrick Mezard <pmezard@gmail.com>
parents: 6847
diff changeset
   677
            kind = self._checkpath(entrypath, revnum)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   678
            if kind == svn.core.svn_node_file:
11127
ab575114ddd8 convert/svn: do not retrieve removed files
Patrick Mezard <pmezard@gmail.com>
parents: 11126
diff changeset
   679
                changed.add(self.recode(entrypath))
6546
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
   680
                if not ent.copyfrom_path or not parents:
6544
3447c088a516 convert: cleanup svn file copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6543
diff changeset
   681
                    continue
8660
b9ec04eb2aa3 convert/subversion: wrap long lines in comments
Martin Geisler <mg@lazybytes.net>
parents: 8339
diff changeset
   682
                # Copy sources not in parent revisions cannot be
b9ec04eb2aa3 convert/subversion: wrap long lines in comments
Martin Geisler <mg@lazybytes.net>
parents: 8339
diff changeset
   683
                # represented, ignore their origin for now
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   684
                pmodule, prevnum = revsplit(parents[0])[1:]
6546
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
   685
                if ent.copyfrom_rev < prevnum:
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
   686
                    continue
075b2c9aed37 convert: fix svn file copy detection code
Patrick Mezard <pmezard@gmail.com>
parents: 6545
diff changeset
   687
                copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule)
6544
3447c088a516 convert: cleanup svn file copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6543
diff changeset
   688
                if not copyfrom_path:
3447c088a516 convert: cleanup svn file copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6543
diff changeset
   689
                    continue
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   690
                self.ui.debug("copied to %s from %s@%s\n" %
6544
3447c088a516 convert: cleanup svn file copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6543
diff changeset
   691
                              (entrypath, copyfrom_path, ent.copyfrom_rev))
8885
2c184bd2b37a convert/svn: remove confusing unicode variable
Patrick Mezard <pmezard@gmail.com>
parents: 8884
diff changeset
   692
                copies[self.recode(entrypath)] = self.recode(copyfrom_path)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   693
            elif kind == 0: # gone, but had better be a deleted *file*
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   694
                self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   695
                pmodule, prevnum = revsplit(parents[0])[1:]
8884
8b603c7c808e convert/svn: remove dead code from entry deletion code path
Patrick Mezard <pmezard@gmail.com>
parents: 8883
diff changeset
   696
                parentpath = pmodule + "/" + entrypath
11128
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   697
                fromkind = self._checkpath(entrypath, prevnum, pmodule)
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
   698
8881
76d3cd914c5e convert/svn: remove dead code and obsolete comments
Patrick Mezard <pmezard@gmail.com>
parents: 8843
diff changeset
   699
                if fromkind == svn.core.svn_node_file:
11127
ab575114ddd8 convert/svn: do not retrieve removed files
Patrick Mezard <pmezard@gmail.com>
parents: 11126
diff changeset
   700
                    removed.add(self.recode(entrypath))
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   701
                elif fromkind == svn.core.svn_node_dir:
11123
8dd69bee71da convert/svn: tree conflicts no longer happen now we use memctx
Patrick Mezard <pmezard@gmail.com>
parents: 10940
diff changeset
   702
                    oroot = parentpath.strip('/')
8dd69bee71da convert/svn: tree conflicts no longer happen now we use memctx
Patrick Mezard <pmezard@gmail.com>
parents: 10940
diff changeset
   703
                    nroot = path.strip('/')
11133
d7b6aab612b4 convert/svn: remove useless sort
Patrick Mezard <pmezard@gmail.com>
parents: 11132
diff changeset
   704
                    children = self._iterfiles(oroot, prevnum)
11132
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   705
                    for childpath in children:
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   706
                        childpath = childpath.replace(oroot, nroot)
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   707
                        childpath = self.getrelpath("/" + childpath, pmodule)
11125
7a5a98fc38e9 convert/svn: remove broken but unused copy filtering code
Patrick Mezard <pmezard@gmail.com>
parents: 11123
diff changeset
   708
                        if childpath:
11127
ab575114ddd8 convert/svn: do not retrieve removed files
Patrick Mezard <pmezard@gmail.com>
parents: 11126
diff changeset
   709
                            removed.add(self.recode(childpath))
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   710
                else:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   711
                    self.ui.debug('unknown path in revision %d: %s\n' % \
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   712
                                  (revnum, path))
12770
614f0d8724ab check-code: find trailing whitespace
Martin Geisler <mg@lazybytes.net>
parents: 12343
diff changeset
   713
            elif kind == svn.core.svn_node_dir:
5870
0d583ade5817 convert: don't scan directories on property changes
Patrick Mezard <pmezard@gmail.com>
parents: 5854
diff changeset
   714
                if ent.action == 'M':
11128
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   715
                    # If the directory just had a prop change,
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   716
                    # then we shouldn't need to look for its children.
5870
0d583ade5817 convert: don't scan directories on property changes
Patrick Mezard <pmezard@gmail.com>
parents: 5854
diff changeset
   717
                    continue
13052
5fb924ee44d5 convert/svn: fix changed files list upon directory replacements
Patrick Mezard <pmezard@gmail.com>
parents: 12770
diff changeset
   718
                if ent.action == 'R' and parents:
11128
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   719
                    # If a directory is replacing a file, mark the previous
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   720
                    # file as deleted
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   721
                    pmodule, prevnum = revsplit(parents[0])[1:]
11128
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   722
                    pkind = self._checkpath(entrypath, prevnum, pmodule)
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   723
                    if pkind == svn.core.svn_node_file:
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   724
                        removed.add(self.recode(entrypath))
13052
5fb924ee44d5 convert/svn: fix changed files list upon directory replacements
Patrick Mezard <pmezard@gmail.com>
parents: 12770
diff changeset
   725
                    elif pkind == svn.core.svn_node_dir:
5fb924ee44d5 convert/svn: fix changed files list upon directory replacements
Patrick Mezard <pmezard@gmail.com>
parents: 12770
diff changeset
   726
                        # We do not know what files were kept or removed,
5fb924ee44d5 convert/svn: fix changed files list upon directory replacements
Patrick Mezard <pmezard@gmail.com>
parents: 12770
diff changeset
   727
                        # mark them all as changed.
5fb924ee44d5 convert/svn: fix changed files list upon directory replacements
Patrick Mezard <pmezard@gmail.com>
parents: 12770
diff changeset
   728
                        for childpath in self._iterfiles(pmodule, prevnum):
5fb924ee44d5 convert/svn: fix changed files list upon directory replacements
Patrick Mezard <pmezard@gmail.com>
parents: 12770
diff changeset
   729
                            childpath = self.getrelpath("/" + childpath)
5fb924ee44d5 convert/svn: fix changed files list upon directory replacements
Patrick Mezard <pmezard@gmail.com>
parents: 12770
diff changeset
   730
                            if childpath:
5fb924ee44d5 convert/svn: fix changed files list upon directory replacements
Patrick Mezard <pmezard@gmail.com>
parents: 12770
diff changeset
   731
                                changed.add(self.recode(childpath))
5870
0d583ade5817 convert: don't scan directories on property changes
Patrick Mezard <pmezard@gmail.com>
parents: 5854
diff changeset
   732
11133
d7b6aab612b4 convert/svn: remove useless sort
Patrick Mezard <pmezard@gmail.com>
parents: 11132
diff changeset
   733
                for childpath in self._iterfiles(path, revnum):
11132
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   734
                    childpath = self.getrelpath("/" + childpath)
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   735
                    if childpath:
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   736
                        changed.add(self.recode(childpath))
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   737
8881
76d3cd914c5e convert/svn: remove dead code and obsolete comments
Patrick Mezard <pmezard@gmail.com>
parents: 8843
diff changeset
   738
                # Handle directory copies
6543
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
   739
                if not ent.copyfrom_path or not parents:
6542
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
   740
                    continue
8660
b9ec04eb2aa3 convert/subversion: wrap long lines in comments
Martin Geisler <mg@lazybytes.net>
parents: 8339
diff changeset
   741
                # Copy sources not in parent revisions cannot be
b9ec04eb2aa3 convert/subversion: wrap long lines in comments
Martin Geisler <mg@lazybytes.net>
parents: 8339
diff changeset
   742
                # represented, ignore their origin for now
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   743
                pmodule, prevnum = revsplit(parents[0])[1:]
6543
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
   744
                if ent.copyfrom_rev < prevnum:
a6e2e60b34d0 convert: handle past or foreign partial svn copies
Patrick Mezard <pmezard@gmail.com>
parents: 6542
diff changeset
   745
                    continue
8882
48a04961b0dd convert/svn: remove useless encoding/decoding calls (issue1676)
Patrick Mezard <pmezard@gmail.com>
parents: 8881
diff changeset
   746
                copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule)
6542
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
   747
                if not copyfrompath:
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
   748
                    continue
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   749
                self.ui.debug("mark %s came from %s:%d\n"
6542
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
   750
                              % (path, copyfrompath, ent.copyfrom_rev))
11133
d7b6aab612b4 convert/svn: remove useless sort
Patrick Mezard <pmezard@gmail.com>
parents: 11132
diff changeset
   751
                children = self._iterfiles(ent.copyfrom_path, ent.copyfrom_rev)
11132
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   752
                for childpath in children:
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   753
                    childpath = self.getrelpath("/" + childpath, pmodule)
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   754
                    if not childpath:
6542
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
   755
                        continue
11132
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   756
                    copytopath = path + childpath[len(copyfrompath):]
6542
e7810e61f7c1 convert: more cleanup in svn directory copy handling
Patrick Mezard <pmezard@gmail.com>
parents: 6541
diff changeset
   757
                    copytopath = self.getrelpath(copytopath)
11132
321b8b2aa20f convert/svn: list files explicitely, stop checking their type
Patrick Mezard <pmezard@gmail.com>
parents: 11130
diff changeset
   758
                    copies[self.recode(copytopath)] = self.recode(childpath)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   759
11137
94afe7bc87a9 convert/svn: report path discovery progress
Patrick Mezard <pmezard@gmail.com>
parents: 11134
diff changeset
   760
        self.ui.progress(_('scanning paths'), None)
11127
ab575114ddd8 convert/svn: do not retrieve removed files
Patrick Mezard <pmezard@gmail.com>
parents: 11126
diff changeset
   761
        changed.update(removed)
ab575114ddd8 convert/svn: do not retrieve removed files
Patrick Mezard <pmezard@gmail.com>
parents: 11126
diff changeset
   762
        return (list(changed), removed, copies)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   763
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   764
    def _fetch_revisions(self, from_revnum, to_revnum):
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   765
        if from_revnum < to_revnum:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   766
            from_revnum, to_revnum = to_revnum, from_revnum
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   767
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
   768
        self.child_cset = None
6545
a7492fb2107b convert: fix svn branch source detection corner case
Patrick Mezard <pmezard@gmail.com>
parents: 6544
diff changeset
   769
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
   770
        def parselogentry(orig_paths, revnum, author, date, message):
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
   771
            """Return the parsed commit object or None, and True if
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   772
            the revision is a branch root.
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   773
            """
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   774
            self.ui.debug("parsing revision %d (%d changes)\n" %
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
   775
                          (revnum, len(orig_paths)))
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
   776
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   777
            branched = False
4810
c2d529f288a1 convert: move some code into common init function
Brendan Cully <brendan@kublai.com>
parents: 4807
diff changeset
   778
            rev = self.revid(revnum)
4837
4cdbaa885d8a convert: svn: some improvements in memory usage
Brendan Cully <brendan@kublai.com>
parents: 4814
diff changeset
   779
            # branch log might return entries for a parent we already have
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   780
8117
2b30d8488819 remove unnecessary outer parenthesis in if-statements
Martin Geisler <mg@lazybytes.net>
parents: 8086
diff changeset
   781
            if rev in self.commits or revnum < to_revnum:
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   782
                return None, branched
4837
4cdbaa885d8a convert: svn: some improvements in memory usage
Brendan Cully <brendan@kublai.com>
parents: 4814
diff changeset
   783
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   784
            parents = []
5958
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
   785
            # check whether this revision is the start of a branch or part
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
   786
            # of a branch renaming
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 8206
diff changeset
   787
            orig_paths = sorted(orig_paths.iteritems())
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   788
            root_paths = [(p, e) for p, e in orig_paths
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   789
                          if self.module.startswith(p)]
5958
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
   790
            if root_paths:
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
   791
                path, ent = root_paths[-1]
5119
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   792
                if ent.copyfrom_path:
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   793
                    branched = True
5958
59dce24933ad convert: follow svn module parent moves
Patrick Mezard <pmezard@gmail.com>
parents: 5957
diff changeset
   794
                    newpath = ent.copyfrom_path + self.module[len(path):]
5119
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   795
                    # ent.copyfrom_rev may not be the actual last revision
7476
6644c111f9e9 convert: backout a7492fb2107b
Patrick Mezard <pmezard@gmail.com>
parents: 7447
diff changeset
   796
                    previd = self.latest(newpath, ent.copyfrom_rev)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   797
                    if previd is not None:
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   798
                        prevmodule, prevnum = revsplit(previd)[1:]
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   799
                        if prevnum >= self.startrev:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   800
                            parents = [previd]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   801
                            self.ui.note(
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   802
                                _('found parent of branch %s at %d: %s\n') %
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10071
diff changeset
   803
                                (self.module, prevnum, prevmodule))
5119
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   804
                else:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   805
                    self.ui.debug("no copyfrom path, don't know what to do.\n")
5119
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   806
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   807
            paths = []
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   808
            # filter out unrelated paths
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
   809
            for path, ent in orig_paths:
6540
55bd855fc0af convert: improve subversion branch filtering
Patrick Mezard <pmezard@gmail.com>
parents: 6539
diff changeset
   810
                if self.getrelpath(path) is None:
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
   811
                    continue
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   812
                paths.append((path, ent))
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   813
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
   814
            # Example SVN datetime. Includes microseconds.
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
   815
            # ISO-8601 conformant
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
   816
            # '2007-01-04T17:35:00.902377Z'
5617
924fd86f0579 convert: fix SVN date parser dropping the final whole second digit
David J. Mellor <dmellor@whistlingcat.com>
parents: 5521
diff changeset
   817
            date = util.parsedate(date[:19] + " UTC", ["%Y-%m-%dT%H:%M:%S"])
17974
337d728e644f convert: add config option to use the local time zone
Julian Cowley <julian@lava.net>
parents: 17537
diff changeset
   818
            if self.ui.configbool('convert', 'localtimezone'):
337d728e644f convert: add config option to use the local time zone
Julian Cowley <julian@lava.net>
parents: 17537
diff changeset
   819
                date = makedatetimestamp(date[0])
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   820
5916
b6deda0f69fa convert: Do not abort with TypeError if svn commit message is None (issue934)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5883
diff changeset
   821
            log = message and self.recode(message) or ''
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
   822
            author = author and self.recode(author) or ''
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   823
            try:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   824
                branch = self.module.split("/")[-1]
13529
9b62cbe81f44 convert/svn: read trunk name once, use None for default
Patrick Mezard <pmezard@gmail.com>
parents: 13494
diff changeset
   825
                if branch == self.trunkname:
9b62cbe81f44 convert/svn: read trunk name once, use None for default
Patrick Mezard <pmezard@gmail.com>
parents: 13494
diff changeset
   826
                    branch = None
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   827
            except IndexError:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   828
                branch = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   829
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
   830
            cset = commit(author=author,
16514
363e808de349 i18n: use locale insensitive format for datetimes as intermediate representation (issue3398)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 16511
diff changeset
   831
                          date=util.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
4957
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4949
diff changeset
   832
                          desc=log,
4795
ea618c5934f3 convert: svn: get parent for branch creation events
Brendan Cully <brendan@kublai.com>
parents: 4794
diff changeset
   833
                          parents=parents,
4873
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4848
diff changeset
   834
                          branch=branch,
8886
0593c5b5b1f0 convert/svn: stop returning unicode revision identifiers
Patrick Mezard <pmezard@gmail.com>
parents: 8885
diff changeset
   835
                          rev=rev)
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
   836
4796
26857a6f9dd0 convert: svn: pull out broken batching code, add alpha tags support
Brendan Cully <brendan@kublai.com>
parents: 4795
diff changeset
   837
            self.commits[rev] = cset
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   838
            # The parents list is *shared* among self.paths and the
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   839
            # commit object. Both will be updated below.
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   840
            self.paths[rev] = (paths, cset.parents)
4796
26857a6f9dd0 convert: svn: pull out broken batching code, add alpha tags support
Brendan Cully <brendan@kublai.com>
parents: 4795
diff changeset
   841
            if self.child_cset and not self.child_cset.parents:
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   842
                self.child_cset.parents[:] = [rev]
4788
62e1b6412b62 convert: svn: add an early return to move most changeset parsing out an indent level
Brendan Cully <brendan@kublai.com>
parents: 4787
diff changeset
   843
            self.child_cset = cset
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   844
            return cset, branched
4796
26857a6f9dd0 convert: svn: pull out broken batching code, add alpha tags support
Brendan Cully <brendan@kublai.com>
parents: 4795
diff changeset
   845
6956
12472a240398 i18n: mark strings for translation in convert extension
Martin Geisler <mg@daimi.au.dk>
parents: 6884
diff changeset
   846
        self.ui.note(_('fetching revision log for "%s" from %d to %d\n') %
4797
09dae950919f convert: svn: autodetect /branches, /tags, /trunk.
Brendan Cully <brendan@kublai.com>
parents: 4796
diff changeset
   847
                     (self.module, from_revnum, to_revnum))
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   848
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   849
        try:
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   850
            firstcset = None
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   851
            lastonbranch = False
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   852
            stream = self._getlog([self.module], from_revnum, to_revnum)
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   853
            try:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   854
                for entry in stream:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   855
                    paths, revnum, author, date, message = entry
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   856
                    if revnum < self.startrev:
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   857
                        lastonbranch = True
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   858
                        break
8172
36b935cad495 Fix subversion convert not detecting empty changesets.
Francis Barber <fedora@barber-family.id.au>
parents: 8155
diff changeset
   859
                    if not paths:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   860
                        self.ui.debug('revision %d has no entries\n' % revnum)
10618
508fda6b8637 convert: handle svn tree with empty roots (issue2079)
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   861
                        # If we ever leave the loop on an empty
508fda6b8637 convert: handle svn tree with empty roots (issue2079)
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   862
                        # revision, do not try to get a parent branch
508fda6b8637 convert: handle svn tree with empty roots (issue2079)
Patrick Mezard <pmezard@gmail.com>
parents: 10282
diff changeset
   863
                        lastonbranch = lastonbranch or revnum == 0
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   864
                        continue
6210
942287cb1f57 Removed trailing spaces from everything except test output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6173
diff changeset
   865
                    cset, lastonbranch = parselogentry(paths, revnum, author,
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   866
                                                       date, message)
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   867
                    if cset:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   868
                        firstcset = cset
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   869
                    if lastonbranch:
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   870
                        break
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   871
            finally:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   872
                stream.close()
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   873
6173
963000ed8cac convert: add shallow, single branch svn conversions via svn.startrev
Patrick Mezard <pmezard@gmail.com>
parents: 6172
diff changeset
   874
            if not lastonbranch and firstcset and not firstcset.parents:
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   875
                # The first revision of the sequence (the last fetched one)
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   876
                # has invalid parents if not a branch root. Find the parent
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   877
                # revision now, if any.
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   878
                try:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   879
                    firstrevnum = self.revnum(firstcset.rev)
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   880
                    if firstrevnum > 1:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   881
                        latest = self.latest(self.module, firstrevnum - 1)
5957
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   882
                        if latest:
971a17af5982 convert: prevent svn branches to leave the root module tree
Patrick Mezard <pmezard@gmail.com>
parents: 5956
diff changeset
   883
                            firstcset.parents.append(latest)
7381
b965605dfb2e convert: be even more tolerant when detecting svn tags
Patrick Mezard <pmezard@gmail.com>
parents: 7184
diff changeset
   884
                except SvnPathNotFound:
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   885
                    pass
5140
792c1d979097 Replace _ with inst for catching exceptions to not shadow gettext.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5139
diff changeset
   886
        except SubversionException, (inst, num):
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   887
            if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16514
diff changeset
   888
                raise util.Abort(_('svn: branch has no revision %s')
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16514
diff changeset
   889
                                 % to_revnum)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   890
            raise
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   891
11134
33010ff1fd6f convert: merge sources getmode() into getfile()
Patrick Mezard <pmezard@gmail.com>
parents: 11133
diff changeset
   892
    def getfile(self, file, rev):
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   893
        # TODO: ra.get_file transmits the whole file instead of diffs.
11127
ab575114ddd8 convert/svn: do not retrieve removed files
Patrick Mezard <pmezard@gmail.com>
parents: 11126
diff changeset
   894
        if file in self.removed:
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16683
diff changeset
   895
            raise IOError
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   896
        mode = ''
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   897
        try:
13690
af331f557942 convert/svn: extract revsplit() in a function
Patrick Mezard <pmezard@gmail.com>
parents: 13653
diff changeset
   898
            new_module, revnum = revsplit(rev)[1:]
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   899
            if self.module != new_module:
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   900
                self.module = new_module
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   901
                self.reparent(self.module)
7446
2d2e0be762be convert: work around svn.ra.get_files() not releasing input buffer
Patrick Mezard <pmezard@gmail.com>
parents: 7382
diff changeset
   902
            io = StringIO()
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   903
            info = svn.ra.get_file(self.ra, file, revnum, io)
7446
2d2e0be762be convert: work around svn.ra.get_files() not releasing input buffer
Patrick Mezard <pmezard@gmail.com>
parents: 7382
diff changeset
   904
            data = io.getvalue()
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17247
diff changeset
   905
            # ra.get_file() seems to keep a reference on the input buffer
17479
17c3dbf3026f spelling: Explicitly
timeless@mozdev.org
parents: 17247
diff changeset
   906
            # preventing collection. Release it explicitly.
7446
2d2e0be762be convert: work around svn.ra.get_files() not releasing input buffer
Patrick Mezard <pmezard@gmail.com>
parents: 7382
diff changeset
   907
            io.close()
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   908
            if isinstance(info, list):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   909
                info = info[-1]
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   910
            mode = ("svn:executable" in info) and 'x' or ''
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   911
            mode = ("svn:special" in info) and 'l' or mode
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   912
        except SubversionException, e:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   913
            notfound = (svn.core.SVN_ERR_FS_NOT_FOUND,
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   914
                svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   915
            if e.apr_err in notfound: # File not found
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16683
diff changeset
   916
                raise IOError
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   917
            raise
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   918
        if mode == 'l':
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   919
            link_prefix = "link "
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   920
            if data.startswith(link_prefix):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   921
                data = data[len(link_prefix):]
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   922
        return data, mode
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   923
11133
d7b6aab612b4 convert/svn: remove useless sort
Patrick Mezard <pmezard@gmail.com>
parents: 11132
diff changeset
   924
    def _iterfiles(self, path, revnum):
d7b6aab612b4 convert/svn: remove useless sort
Patrick Mezard <pmezard@gmail.com>
parents: 11132
diff changeset
   925
        """Enumerate all files in path at revnum, recursively."""
5114
35f67dd712d0 convert: svn: ensure leading / is removed from paths in _find_children (broken in 2bd996d0aaf8)
Brendan Cully <brendan@kublai.com>
parents: 5050
diff changeset
   926
        path = path.strip('/')
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   927
        pool = Pool()
15599
c6be93a4c378 convert/svn: fix URL quoting issue with svn 1.7
Patrick Mezard <pmezard@gmail.com>
parents: 15381
diff changeset
   928
        rpath = '/'.join([self.baseurl, quote(path)]).strip('/')
11167
b5ef95b5ae14 convert/svn: fix long line
Matt Mackall <mpm@selenic.com>
parents: 11137
diff changeset
   929
        entries = svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool)
13651
9777df929035 convert/svn: fix _iterfiles() output in root dir case (issue2647)
Patrick Mezard <pmezard@gmail.com>
parents: 13494
diff changeset
   930
        if path:
9777df929035 convert/svn: fix _iterfiles() output in root dir case (issue2647)
Patrick Mezard <pmezard@gmail.com>
parents: 13494
diff changeset
   931
            path += '/'
9777df929035 convert/svn: fix _iterfiles() output in root dir case (issue2647)
Patrick Mezard <pmezard@gmail.com>
parents: 13494
diff changeset
   932
        return ((path + p) for p, e in entries.iteritems()
11133
d7b6aab612b4 convert/svn: remove useless sort
Patrick Mezard <pmezard@gmail.com>
parents: 11132
diff changeset
   933
                if e.kind == svn.core.svn_node_file)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   934
6539
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   935
    def getrelpath(self, path, module=None):
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   936
        if module is None:
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   937
            module = self.module
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   938
        # Given the repository url of this wc, say
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   939
        #   "http://server/plone/CMFPlone/branches/Plone-2_0-branch"
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   940
        # extract the "entry" portion (a relative path) from what
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17247
diff changeset
   941
        # svn log --xml says, i.e.
6539
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   942
        #   "/CMFPlone/branches/Plone-2_0-branch/tests/PloneTestCase.py"
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   943
        # that is to say "tests/PloneTestCase.py"
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   944
        if path.startswith(module):
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   945
            relative = path.rstrip('/')[len(module):]
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   946
            if relative.startswith('/'):
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   947
                return relative[1:]
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   948
            elif relative == '':
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   949
                return relative
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   950
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   951
        # The path is outside our tracked tree...
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9312
diff changeset
   952
        self.ui.debug('%r is not under %r, ignoring\n' % (path, module))
6539
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   953
        return None
7814d7bb77bc convert: rename get_entry_from_path() into an svn_source method
Patrick Mezard <pmezard@gmail.com>
parents: 6538
diff changeset
   954
11128
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   955
    def _checkpath(self, path, revnum, module=None):
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   956
        if module is not None:
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   957
            prevmodule = self.reparent('')
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   958
            path = module + '/' + path
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   959
        try:
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   960
            # ra.check_path does not like leading slashes very much, it leads
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   961
            # to PROPFIND subversion errors
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   962
            return svn.ra.check_path(self.ra, path.strip('/'), revnum)
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   963
        finally:
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   964
            if module is not None:
a9b427b5821e convert/svn: handle files/links replaced by dirs (issue2166)
Patrick Mezard <pmezard@gmail.com>
parents: 11127
diff changeset
   965
                self.reparent(prevmodule)
12770
614f0d8724ab check-code: find trailing whitespace
Martin Geisler <mg@lazybytes.net>
parents: 12343
diff changeset
   966
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   967
    def _getlog(self, paths, start, end, limit=0, discover_changed_paths=True,
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   968
                strict_node_history=False):
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   969
        # Normalize path names, svn >= 1.5 only wants paths relative to
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   970
        # supplied URL
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   971
        relpaths = []
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   972
        for p in paths:
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   973
            if not p.startswith('/'):
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   974
                p = self.module + '/' + p
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   975
            relpaths.append(p.strip('/'))
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16514
diff changeset
   976
        args = [self.baseurl, relpaths, start, end, limit,
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16514
diff changeset
   977
                discover_changed_paths, strict_node_history]
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   978
        arg = encodeargs(args)
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   979
        hgexe = util.hgexecutable()
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   980
        cmd = '%s debugsvnlog' % util.shellquote(hgexe)
13190
5314cbb775f6 convert: subversion should use util.quotecommand to wrap args to popen2
Steve Borho <steve@borho.org>
parents: 13052
diff changeset
   981
        stdin, stdout = util.popen2(util.quotecommand(cmd))
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   982
        stdin.write(arg)
10071
661980567246 convert/svn: better handling of hg recursive call failure
Patrick Mezard <pmezard@gmail.com>
parents: 10051
diff changeset
   983
        try:
661980567246 convert/svn: better handling of hg recursive call failure
Patrick Mezard <pmezard@gmail.com>
parents: 10051
diff changeset
   984
            stdin.close()
661980567246 convert/svn: better handling of hg recursive call failure
Patrick Mezard <pmezard@gmail.com>
parents: 10051
diff changeset
   985
        except IOError:
661980567246 convert/svn: better handling of hg recursive call failure
Patrick Mezard <pmezard@gmail.com>
parents: 10051
diff changeset
   986
            raise util.Abort(_('Mercurial failed to run itself, check'
661980567246 convert/svn: better handling of hg recursive call failure
Patrick Mezard <pmezard@gmail.com>
parents: 10051
diff changeset
   987
                               ' hg executable is in PATH'))
6850
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   988
        return logstream(stdout)
c6bb8fae3bd2 convert: normalize paths sent to svn get_log (issue 1219)
Patrick Mezard <pmezard@gmail.com>
parents: 6848
diff changeset
   989
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   990
pre_revprop_change = '''#!/bin/sh
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   991
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   992
REPOS="$1"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   993
REV="$2"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   994
USER="$3"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   995
PROPNAME="$4"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   996
ACTION="$5"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   997
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   998
if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   999
if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-branch" ]; then exit 0; fi
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1000
if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-rev" ]; then exit 0; fi
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1001
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1002
echo "Changing prohibited revision property" >&2
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1003
exit 1
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1004
'''
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1005
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1006
class svn_sink(converter_sink, commandline):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1007
    commit_re = re.compile(r'Committed revision (\d+).', re.M)
13530
5f69af0d2fb3 convert/svn: stop using svn bindings when pushing to svn
Patrick Mezard <pmezard@gmail.com>
parents: 13529
diff changeset
  1008
    uuid_re = re.compile(r'Repository UUID:\s*(\S+)', re.M)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1009
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1010
    def prerun(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1011
        if self.wc:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1012
            os.chdir(self.wc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1013
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1014
    def postrun(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1015
        if self.wc:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1016
            os.chdir(self.cwd)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1017
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1018
    def join(self, name):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1019
        return os.path.join(self.wc, '.svn', name)
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5705
diff changeset
  1020
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1021
    def revmapfile(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1022
        return self.join('hg-shamap')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1023
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1024
    def authorfile(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1025
        return self.join('hg-authormap')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1026
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1027
    def __init__(self, ui, path):
13480
69418d4525d1 convert/svn: abort operation when python bindings are not available
Azhagu Selvan SP <tamizhgeek@gmail.com>
parents: 13190
diff changeset
  1028
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1029
        converter_sink.__init__(self, ui, path)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1030
        commandline.__init__(self, ui, 'svn')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1031
        self.delete = []
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1032
        self.setexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1033
        self.delexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1034
        self.copies = []
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1035
        self.wc = None
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1036
        self.cwd = os.getcwd()
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1037
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1038
        created = False
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1039
        if os.path.isfile(os.path.join(path, '.svn', 'entries')):
17247
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1040
            self.wc = os.path.realpath(path)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1041
            self.run0('update')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1042
        else:
17247
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1043
            if not re.search(r'^(file|http|https|svn|svn\+ssh)\://', path):
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1044
                path = os.path.realpath(path)
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1045
                if os.path.isdir(os.path.dirname(path)):
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1046
                    if not os.path.exists(os.path.join(path, 'db', 'fs-type')):
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1047
                        ui.status(_('initializing svn repository %r\n') %
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1048
                                  os.path.basename(path))
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1049
                        commandline(ui, 'svnadmin').run0('create', path)
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1050
                        created = path
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1051
                    path = util.normpath(path)
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1052
                    if not path.startswith('/'):
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1053
                        path = '/' + path
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1054
                    path = 'file://' + path
5535
7501ef26402b convert: fix svn file:// URL generation under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5528
diff changeset
  1055
17247
6d51a0c71d4e convert/svn: handle non-local svn destination paths (issue3142)
Patrick Mezard <patrick@mezard.eu>
parents: 17053
diff changeset
  1056
            wcpath = os.path.join(os.getcwd(), os.path.basename(path) + '-wc')
10940
898d68468df2 convert: write "working copy" instead of "wc"
Martin Geisler <mg@lazybytes.net>
parents: 10939
diff changeset
  1057
            ui.status(_('initializing svn working copy %r\n')
898d68468df2 convert: write "working copy" instead of "wc"
Martin Geisler <mg@lazybytes.net>
parents: 10939
diff changeset
  1058
                      % os.path.basename(wcpath))
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1059
            self.run0('checkout', path, wcpath)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1060
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1061
            self.wc = wcpath
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13690
diff changeset
  1062
        self.opener = scmutil.opener(self.wc)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13690
diff changeset
  1063
        self.wopener = scmutil.opener(self.wc)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1064
        self.childmap = mapfile(ui, self.join('hg-childmap'))
14273
38af0f514134 rename util.is_exec to isexec
Adrian Buehlmann <adrian@cadifra.com>
parents: 14233
diff changeset
  1065
        self.is_exec = util.checkexec(self.wc) and util.isexec or None
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1066
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1067
        if created:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1068
            hook = os.path.join(created, 'hooks', 'pre-revprop-change')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1069
            fp = open(hook, 'w')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1070
            fp.write(pre_revprop_change)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1071
            fp.close()
14232
df2399663392 rename util.set_flags to setflags
Adrian Buehlmann <adrian@cadifra.com>
parents: 14168
diff changeset
  1072
            util.setflags(hook, False, True)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1073
13530
5f69af0d2fb3 convert/svn: stop using svn bindings when pushing to svn
Patrick Mezard <pmezard@gmail.com>
parents: 13529
diff changeset
  1074
        output = self.run0('info')
5f69af0d2fb3 convert/svn: stop using svn bindings when pushing to svn
Patrick Mezard <pmezard@gmail.com>
parents: 13529
diff changeset
  1075
        self.uuid = self.uuid_re.search(output).group(1).strip()
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
  1076
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1077
    def wjoin(self, *names):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1078
        return os.path.join(self.wc, *names)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1079
16511
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1080
    @propertycache
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1081
    def manifest(self):
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1082
        # As of svn 1.7, the "add" command fails when receiving
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1083
        # already tracked entries, so we have to track and filter them
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1084
        # ourselves.
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1085
        m = set()
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1086
        output = self.run0('ls', recursive=True, xml=True)
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1087
        doc = xml.dom.minidom.parseString(output)
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1088
        for e in doc.getElementsByTagName('entry'):
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1089
            for n in e.childNodes:
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1090
                if n.nodeType != n.ELEMENT_NODE or n.tagName != 'name':
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1091
                    continue
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1092
                name = ''.join(c.data for c in n.childNodes
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1093
                               if c.nodeType == c.TEXT_NODE)
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1094
                # Entries are compared with names coming from
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1095
                # mercurial, so bytes with undefined encoding. Our
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1096
                # best bet is to assume they are in local
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1097
                # encoding. They will be passed to command line calls
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1098
                # later anyway, so they better be.
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1099
                m.add(encoding.tolocal(name.encode('utf-8')))
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1100
                break
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1101
        return m
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1102
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1103
    def putfile(self, filename, flags, data):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1104
        if 'l' in flags:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1105
            self.wopener.symlink(data, filename)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1106
        else:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1107
            try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1108
                if os.path.islink(self.wjoin(filename)):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1109
                    os.unlink(filename)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1110
            except OSError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1111
                pass
14168
135e244776f0 prevent transient leaks of file handle by using new helper functions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14152
diff changeset
  1112
            self.wopener.write(filename, data)
5536
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
  1113
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
  1114
            if self.is_exec:
17031
f17b561cc473 convert: ignore svn:executable for subversion targets without exec bit support
Mads Kiilerich <mads@kiilerich.com>
parents: 16925
diff changeset
  1115
                if self.is_exec(self.wjoin(filename)):
f17b561cc473 convert: ignore svn:executable for subversion targets without exec bit support
Mads Kiilerich <mads@kiilerich.com>
parents: 16925
diff changeset
  1116
                    if 'x' not in flags:
f17b561cc473 convert: ignore svn:executable for subversion targets without exec bit support
Mads Kiilerich <mads@kiilerich.com>
parents: 16925
diff changeset
  1117
                        self.delexec.append(filename)
f17b561cc473 convert: ignore svn:executable for subversion targets without exec bit support
Mads Kiilerich <mads@kiilerich.com>
parents: 16925
diff changeset
  1118
                else:
f17b561cc473 convert: ignore svn:executable for subversion targets without exec bit support
Mads Kiilerich <mads@kiilerich.com>
parents: 16925
diff changeset
  1119
                    if 'x' in flags:
f17b561cc473 convert: ignore svn:executable for subversion targets without exec bit support
Mads Kiilerich <mads@kiilerich.com>
parents: 16925
diff changeset
  1120
                        self.setexec.append(filename)
f17b561cc473 convert: ignore svn:executable for subversion targets without exec bit support
Mads Kiilerich <mads@kiilerich.com>
parents: 16925
diff changeset
  1121
                util.setflags(self.wjoin(filename), False, 'x' in flags)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1122
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1123
    def _copyfile(self, source, dest):
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1124
        # SVN's copy command pukes if the destination file exists, but
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1125
        # our copyfile method expects to record a copy that has
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1126
        # already occurred.  Cross the semantic gap.
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1127
        wdest = self.wjoin(dest)
12343
28642f7fc2cf convert/svn: fix broken symlink renames in svn sink
Patrick Mezard <pmezard@gmail.com>
parents: 11779
diff changeset
  1128
        exists = os.path.lexists(wdest)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1129
        if exists:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1130
            fd, tempname = tempfile.mkstemp(
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1131
                prefix='hg-copy-', dir=os.path.dirname(wdest))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1132
            os.close(fd)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1133
            os.unlink(tempname)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1134
            os.rename(wdest, tempname)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1135
        try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1136
            self.run0('copy', source, dest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1137
        finally:
16511
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1138
            self.manifest.add(dest)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1139
            if exists:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1140
                try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1141
                    os.unlink(wdest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1142
                except OSError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1143
                    pass
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1144
                os.rename(tempname, wdest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1145
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1146
    def dirs_of(self, files):
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8129
diff changeset
  1147
        dirs = set()
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1148
        for f in files:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1149
            if os.path.isdir(self.wjoin(f)):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1150
                dirs.add(f)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1151
            for i in strutil.rfindall(f, '/'):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1152
                dirs.add(f[:i])
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1153
        return dirs
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1154
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1155
    def add_dirs(self, files):
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 8206
diff changeset
  1156
        add_dirs = [d for d in sorted(self.dirs_of(files))
16511
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1157
                    if d not in self.manifest]
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1158
        if add_dirs:
16511
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1159
            self.manifest.update(add_dirs)
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
  1160
            self.xargs(add_dirs, 'add', non_recursive=True, quiet=True)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1161
        return add_dirs
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1162
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1163
    def add_files(self, files):
16511
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1164
        files = [f for f in files if f not in self.manifest]
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1165
        if files:
16511
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1166
            self.manifest.update(files)
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
  1167
            self.xargs(files, 'add', quiet=True)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1168
        return files
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5705
diff changeset
  1169
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1170
    def tidy_dirs(self, names):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1171
        deleted = []
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 8206
diff changeset
  1172
        for d in sorted(self.dirs_of(names), reverse=True):
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1173
            wd = self.wjoin(d)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1174
            if os.listdir(wd) == '.svn':
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1175
                self.run0('delete', d)
16511
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1176
                self.manifest.remove(d)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1177
                deleted.append(d)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1178
        return deleted
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1179
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1180
    def addchild(self, parent, child):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1181
        self.childmap[parent] = child
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1182
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
  1183
    def revid(self, rev):
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
  1184
        return u"svn:%s@%s" % (self.uuid, rev)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1185
8693
68e0a55eee6e convert: rewrite tags when converting from hg to hg
Patrick Mezard <pmezard@gmail.com>
parents: 8660
diff changeset
  1186
    def putcommit(self, files, copies, parents, commit, source, revmap):
15605
2ad5b8937d0d convert/svn: update svn working copy only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15599
diff changeset
  1187
        for parent in parents:
2ad5b8937d0d convert/svn: update svn working copy only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15599
diff changeset
  1188
            try:
2ad5b8937d0d convert/svn: update svn working copy only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15599
diff changeset
  1189
                return self.revid(self.childmap[parent])
2ad5b8937d0d convert/svn: update svn working copy only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15599
diff changeset
  1190
            except KeyError:
2ad5b8937d0d convert/svn: update svn working copy only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15599
diff changeset
  1191
                pass
2ad5b8937d0d convert/svn: update svn working copy only when necessary
Patrick Mezard <pmezard@gmail.com>
parents: 15599
diff changeset
  1192
6716
c9b8d2565b92 convert: reintegrate file retrieval code in sinks
Patrick Mezard <pmezard@gmail.com>
parents: 6557
diff changeset
  1193
        # Apply changes to working copy
c9b8d2565b92 convert: reintegrate file retrieval code in sinks
Patrick Mezard <pmezard@gmail.com>
parents: 6557
diff changeset
  1194
        for f, v in files:
c9b8d2565b92 convert: reintegrate file retrieval code in sinks
Patrick Mezard <pmezard@gmail.com>
parents: 6557
diff changeset
  1195
            try:
11134
33010ff1fd6f convert: merge sources getmode() into getfile()
Patrick Mezard <pmezard@gmail.com>
parents: 11133
diff changeset
  1196
                data, mode = source.getfile(f, v)
7875
553aa0cbeab6 cleanup: drop unused assignments
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 7874
diff changeset
  1197
            except IOError:
6716
c9b8d2565b92 convert: reintegrate file retrieval code in sinks
Patrick Mezard <pmezard@gmail.com>
parents: 6557
diff changeset
  1198
                self.delete.append(f)
c9b8d2565b92 convert: reintegrate file retrieval code in sinks
Patrick Mezard <pmezard@gmail.com>
parents: 6557
diff changeset
  1199
            else:
11134
33010ff1fd6f convert: merge sources getmode() into getfile()
Patrick Mezard <pmezard@gmail.com>
parents: 11133
diff changeset
  1200
                self.putfile(f, mode, data)
6716
c9b8d2565b92 convert: reintegrate file retrieval code in sinks
Patrick Mezard <pmezard@gmail.com>
parents: 6557
diff changeset
  1201
                if f in copies:
c9b8d2565b92 convert: reintegrate file retrieval code in sinks
Patrick Mezard <pmezard@gmail.com>
parents: 6557
diff changeset
  1202
                    self.copies.append([copies[f], f])
c9b8d2565b92 convert: reintegrate file retrieval code in sinks
Patrick Mezard <pmezard@gmail.com>
parents: 6557
diff changeset
  1203
        files = [f[0] for f in files]
c9b8d2565b92 convert: reintegrate file retrieval code in sinks
Patrick Mezard <pmezard@gmail.com>
parents: 6557
diff changeset
  1204
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8129
diff changeset
  1205
        entries = set(self.delete)
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 8129
diff changeset
  1206
        files = frozenset(files)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1207
        entries.update(self.add_dirs(files.difference(entries)))
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1208
        if self.copies:
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1209
            for s, d in self.copies:
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1210
                self._copyfile(s, d)
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1211
            self.copies = []
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1212
        if self.delete:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
  1213
            self.xargs(self.delete, 'delete')
16511
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1214
            for f in self.delete:
ecd2fbe68b25 convert/svn: make svn sink work with svn 1.7
Patrick Mezard <patrick@mezard.eu>
parents: 16466
diff changeset
  1215
                self.manifest.remove(f)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1216
            self.delete = []
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1217
        entries.update(self.add_files(files.difference(entries)))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1218
        entries.update(self.tidy_dirs(entries))
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1219
        if self.delexec:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
  1220
            self.xargs(self.delexec, 'propdel', 'svn:executable')
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1221
            self.delexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1222
        if self.setexec:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
  1223
            self.xargs(self.setexec, 'propset', 'svn:executable', '*')
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1224
            self.setexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
  1225
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1226
        fd, messagefile = tempfile.mkstemp(prefix='hg-convert-')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1227
        fp = os.fdopen(fd, 'w')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1228
        fp.write(commit.desc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1229
        fp.close()
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1230
        try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1231
            output = self.run0('commit',
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1232
                               username=util.shortuser(commit.author),
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1233
                               file=messagefile,
5790
f85c0034a062 convert: svn_sink: workaround of command line size limitation on win32.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5789
diff changeset
  1234
                               encoding='utf-8')
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1235
            try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1236
                rev = self.commit_re.search(output).group(1)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1237
            except AttributeError:
10051
a02d43acbc04 convert/svn: make sink recover gracefully from empty changeset
Patrick Mezard <pmezard@gmail.com>
parents: 9860
diff changeset
  1238
                if not files:
a02d43acbc04 convert/svn: make sink recover gracefully from empty changeset
Patrick Mezard <pmezard@gmail.com>
parents: 9860
diff changeset
  1239
                    return parents[0]
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1240
                self.ui.warn(_('unexpected svn output:\n'))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1241
                self.ui.warn(output)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1242
                raise util.Abort(_('unable to cope with svn output'))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1243
            if commit.rev:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1244
                self.run('propset', 'hg:convert-rev', commit.rev,
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1245
                         revprop=True, revision=rev)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1246
            if commit.branch and commit.branch != 'default':
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1247
                self.run('propset', 'hg:convert-branch', commit.branch,
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1248
                         revprop=True, revision=rev)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1249
            for parent in parents:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1250
                self.addchild(parent, rev)
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
  1251
            return self.revid(rev)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1252
        finally:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1253
            os.unlink(messagefile)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1254
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
  1255
    def puttags(self, tags):
11779
2b7a75ca6913 convert: less shouting in SVN sink warning
Martin Geisler <mg@aragost.com>
parents: 11778
diff changeset
  1256
        self.ui.warn(_('writing Subversion tags is not yet implemented\n'))
11778
7e5f5e5858f9 convert: Using --dest-type svn crashed, if the source repo used tags.
Daniel J. Lauk <daniel.lauk@gmail.com>
parents: 11196
diff changeset
  1257
        return None, None
16106
d75aa756149b convert: use splicemap entries when sorting revisions (issue1748)
Patrick Mezard <patrick@mezard.eu>
parents: 16067
diff changeset
  1258
d75aa756149b convert: use splicemap entries when sorting revisions (issue1748)
Patrick Mezard <patrick@mezard.eu>
parents: 16067
diff changeset
  1259
    def hascommit(self, rev):
d75aa756149b convert: use splicemap entries when sorting revisions (issue1748)
Patrick Mezard <patrick@mezard.eu>
parents: 16067
diff changeset
  1260
        # This is not correct as one can convert to an existing subversion
d75aa756149b convert: use splicemap entries when sorting revisions (issue1748)
Patrick Mezard <patrick@mezard.eu>
parents: 16067
diff changeset
  1261
        # repository and childmap would not list all revisions. Too bad.
d75aa756149b convert: use splicemap entries when sorting revisions (issue1748)
Patrick Mezard <patrick@mezard.eu>
parents: 16067
diff changeset
  1262
        if rev in self.childmap:
d75aa756149b convert: use splicemap entries when sorting revisions (issue1748)
Patrick Mezard <patrick@mezard.eu>
parents: 16067
diff changeset
  1263
            return True
d75aa756149b convert: use splicemap entries when sorting revisions (issue1748)
Patrick Mezard <patrick@mezard.eu>
parents: 16067
diff changeset
  1264
        raise util.Abort(_('splice map revision %s not found in subversion '
16162
7e279d475669 convert: fix typos in error messages
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 16106
diff changeset
  1265
                           'child map (revision lookups are not implemented)')
16106
d75aa756149b convert: use splicemap entries when sorting revisions (issue1748)
Patrick Mezard <patrick@mezard.eu>
parents: 16067
diff changeset
  1266
                         % rev)