hgext/convert/subversion.py
author Thomas Arendsen Hein <thomas@intevation.de>
Tue, 22 Jan 2008 00:55:01 +0100
changeset 5921 549a7ebe1607
parent 5913 7c2921a60035
parent 5916 b6deda0f69fa
child 5955 c4496b7c10ce
permissions -rw-r--r--
merge with crew-stable
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
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
     4
#
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
     5
# Configuration options:
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
     6
#
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
     7
# convert.svn.trunk
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
     8
#   Relative path to the trunk (default: "trunk")
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
     9
# convert.svn.branches
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
    10
#   Relative path to tree of branches (default: "branches")
5462
91a522a69c13 convert: svn -- fix tags handling
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5461
diff changeset
    11
# convert.svn.tags
91a522a69c13 convert: svn -- fix tags handling
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5461
diff changeset
    12
#   Relative path to tree of tags (default: "tags")
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
    13
#
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
    14
# Set these in a hgrc, or on the command line as follows:
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
    15
#
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
    16
#   hg convert --config convert.svn.trunk=wackoname [...]
4765
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
import locale
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
    19
import os
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
    20
import re
5139
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
    21
import sys
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
    22
import cPickle as pickle
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
    23
import tempfile
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
    24
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
    25
from mercurial import strutil, util
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
    26
from mercurial.i18n import _
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    27
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    28
# Subversion stuff. Works best with very recent Python SVN bindings
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    29
# 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
    30
# these bindings.
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    31
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    32
from cStringIO import StringIO
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    33
5139
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
    34
from common import NoRepo, commit, converter_source, encodeargs, decodeargs
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
    35
from common import commandline, converter_sink, mapfile
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    36
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    37
try:
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    38
    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
    39
    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
    40
    import svn.client
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    41
    import svn.core
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    42
    import svn.ra
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    43
    import svn.delta
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    44
    import transport
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    45
except ImportError:
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
    46
    pass
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
    47
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
    48
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
    49
    try:
5020
780051cca03c convert svn: canonicalize path before calling url_from_path.
Brendan Cully <brendan@kublai.com>
parents: 5010
diff changeset
    50
        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
    51
    except SubversionException:
6b2d8caf87b2 convert svn: try to extract URL from source if it is a working directory
Brendan Cully <brendan@kublai.com>
parents: 5008
diff changeset
    52
        pass
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
    53
    if os.path.isdir(path):
5793
68f5bf9aa582 convert: Accept local path on win32.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5790
diff changeset
    54
        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
    55
        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
    56
            path = '/' + util.normpath(path)
5793
68f5bf9aa582 convert: Accept local path on win32.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5790
diff changeset
    57
        return 'file://%s' % path
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
    58
    return path
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
    59
5117
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    60
def optrev(number):
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    61
    optrev = svn.core.svn_opt_revision_t()
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    62
    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
    63
    optrev.value.number = number
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    64
    return optrev
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
    65
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
    66
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
    67
    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
    68
        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
    69
        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
    70
        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
    71
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    72
def get_log_child(fp, url, paths, start, end, limit=0, discover_changed_paths=True,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    73
                    strict_node_history=False):
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    74
    protocol = -1
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    75
    def receiver(orig_paths, revnum, author, date, message, pool):
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    76
        if orig_paths is not None:
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    77
            for k, v in orig_paths.iteritems():
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    78
                orig_paths[k] = changedpath(v)
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    79
        pickle.dump((orig_paths, revnum, author, date, message),
5143
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5141
diff changeset
    80
                    fp, protocol)
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5141
diff changeset
    81
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    82
    try:
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    83
        # 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
    84
        # our results without confusing the server.
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    85
        t = transport.SvnRaTransport(url=url)
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    86
        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
    87
                       discover_changed_paths,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    88
                       strict_node_history,
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    89
                       receiver)
5140
792c1d979097 Replace _ with inst for catching exceptions to not shadow gettext.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5139
diff changeset
    90
    except SubversionException, (inst, num):
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    91
        pickle.dump(num, fp, protocol)
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
    92
    except IOError:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
    93
        # Caller may interrupt the iteration
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
    94
        pickle.dump(None, fp, protocol)
5127
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    95
    else:
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    96
        pickle.dump(None, fp, protocol)
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    97
    fp.close()
39b6eaee6fd7 convert: replace fork with subprocess call.
Patrick Mezard <pmezard@gmail.com>
parents: 5122
diff changeset
    98
5139
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
    99
def debugsvnlog(ui, **opts):
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   100
    """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
   101
    avoid memory collection issues.
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   102
    """
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   103
    util.set_binary(sys.stdin)
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   104
    util.set_binary(sys.stdout)
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   105
    args = decodeargs(sys.stdin.read())
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   106
    get_log_child(sys.stdout, *args)
18abf13064cb Move debugsvnlog to subversion module.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5138
diff changeset
   107
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   108
class logstream:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   109
    """Interruptible revision log iterator."""
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   110
    def __init__(self, stdout):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   111
        self._stdout = stdout
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   112
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   113
    def __iter__(self):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   114
        while True:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   115
            entry = pickle.load(self._stdout)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   116
            try:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   117
                orig_paths, revnum, author, date, message = entry
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   118
            except:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   119
                if entry is None:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   120
                    break
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   121
                raise SubversionException("child raised exception", entry)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   122
            yield entry
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   123
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   124
    def close(self):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   125
        if self._stdout:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   126
            self._stdout.close()
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   127
            self._stdout = None
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   128
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   129
def get_log(url, paths, start, end, limit=0, discover_changed_paths=True,
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   130
                strict_node_history=False):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   131
    args = [url, paths, start, end, limit, discover_changed_paths,
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   132
            strict_node_history]
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   133
    arg = encodeargs(args)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   134
    hgexe = util.hgexecutable()
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   135
    cmd = '%s debugsvnlog' % util.shellquote(hgexe)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   136
    stdin, stdout = os.popen2(cmd, 'b')
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   137
    stdin.write(arg)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   138
    stdin.close()
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   139
    return logstream(stdout)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   140
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   141
# 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
   142
#
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   143
# Subversion looks like a versioned filesystem, branches structures
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   144
# 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
   145
# 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
   146
# children directories. Revisions are then identified by their
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   147
# module and revision number (and a repository identifier).
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   148
#
fb93c774dfff convert: document the subversion conversion model
Patrick Mezard <pmezard@gmail.com>
parents: 5875
diff changeset
   149
# 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
   150
# 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
   151
# 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
   152
# 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
   153
# 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
   154
#
5438
6fa5258be3d4 convert: rename convert_svn to svn_source
Bryan O'Sullivan <bos@serpentine.com>
parents: 5437
diff changeset
   155
class svn_source(converter_source):
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   156
    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
   157
        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
   158
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   159
        try:
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   160
            SubversionException
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   161
        except NameError:
5521
03496d4fa509 convert: display all errors if we couldn't open the source repo
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5462
diff changeset
   162
            raise NoRepo('Subversion python bindings could not be loaded')
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   163
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   164
        self.encoding = locale.getpreferredencoding()
4813
1fcdf2fe3d7c convert: svn: use revmap to parse only new revisions in incremental conversions
Brendan Cully <brendan@kublai.com>
parents: 4811
diff changeset
   165
        self.lastrevs = {}
1fcdf2fe3d7c convert: svn: use revmap to parse only new revisions in incremental conversions
Brendan Cully <brendan@kublai.com>
parents: 4811
diff changeset
   166
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   167
        latest = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   168
        try:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   169
            # Support file://path@rev syntax. Useful e.g. to convert
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   170
            # 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
   171
            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
   172
            if at >= 0:
5e89b0dafce5 convert/subversion.py: str.rsplit is not available in Python 2.3
Bryan O'Sullivan <bos@serpentine.com>
parents: 4925
diff changeset
   173
                latest = int(url[at+1:])
5e89b0dafce5 convert/subversion.py: str.rsplit is not available in Python 2.3
Bryan O'Sullivan <bos@serpentine.com>
parents: 4925
diff changeset
   174
                url = url[:at]
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   175
        except ValueError, e:
4766
95cbb6b74790 convert: activate subversion engine
Brendan Cully <brendan@kublai.com>
parents: 4765
diff changeset
   176
            pass
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
   177
        self.url = geturl(url)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   178
        self.encoding = 'UTF-8' # Subversion is always nominal UTF-8
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   179
        try:
5008
b6c3abdbe0eb convert: urlify svn repos if necessary.
Brendan Cully <brendan@kublai.com>
parents: 4960
diff changeset
   180
            self.transport = transport.SvnRaTransport(url=self.url)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   181
            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
   182
            self.ctx = self.transport.client
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   183
            self.base = svn.ra.get_repos_root(self.ra)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   184
            self.module = self.url[len(self.base):]
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   185
            self.commits = {}
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   186
            self.paths = {}
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   187
            self.uuid = svn.ra.get_uuid(self.ra).decode(self.encoding)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   188
        except SubversionException, e:
5437
4d34f8b12a9e convert: report errors more meaningfully if run with --traceback
Bryan O'Sullivan <bos@serpentine.com>
parents: 5415
diff changeset
   189
            ui.print_exc()
5521
03496d4fa509 convert: display all errors if we couldn't open the source repo
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5462
diff changeset
   190
            raise NoRepo("%s does not look like a Subversion repo" % self.url)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   191
5145
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   192
        if rev:
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   193
            try:
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   194
                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
   195
            except ValueError:
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   196
                raise util.Abort('svn: revision %s is not an integer' % rev)
0751c25ea0c0 raise util.Abort again if specified revision is not an integer.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5144
diff changeset
   197
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   198
        try:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   199
            self.get_blacklist()
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   200
        except IOError, e:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   201
            pass
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   202
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   203
        self.last_changed = self.latest(self.module, latest)
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   204
4810
c2d529f288a1 convert: move some code into common init function
Brendan Cully <brendan@kublai.com>
parents: 4807
diff changeset
   205
        self.head = self.revid(self.last_changed)
5382
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   206
        self._changescache = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   207
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   208
        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
   209
            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
   210
        else:
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   211
            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
   212
        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
   213
5510
11d7908a3ea8 convert: abstract map files into a class
Bryan O'Sullivan <bos@serpentine.com>
parents: 5462
diff changeset
   214
    def setrevmap(self, revmap):
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   215
        lastrevs = {}
5511
03bb1296a1c3 convert: iterate
Bryan O'Sullivan <bos@serpentine.com>
parents: 5510
diff changeset
   216
        for revid in revmap.iterkeys():
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   217
            uuid, module, revnum = self.revsplit(revid)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   218
            lastrevnum = lastrevs.setdefault(module, revnum)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   219
            if revnum > lastrevnum:
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   220
                lastrevs[module] = revnum
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   221
        self.lastrevs = lastrevs
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   222
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   223
    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
   224
        try:
5461
ab4d2e9f3b97 convert: svn -- fix 'exists'
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5438
diff changeset
   225
            svn.client.ls(self.url.rstrip('/') + '/' + path,
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   226
                                 optrev, False, self.ctx)
5461
ab4d2e9f3b97 convert: svn -- fix 'exists'
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5438
diff changeset
   227
            return True
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   228
        except SubversionException, err:
5461
ab4d2e9f3b97 convert: svn -- fix 'exists'
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5438
diff changeset
   229
            return False
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   230
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   231
    def getheads(self):
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   232
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   233
        def getcfgpath(name, rev):
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   234
            cfgpath = self.ui.config('convert', 'svn.' + name)
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   235
            path = (cfgpath or name).strip('/')
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   236
            if not self.exists(path, rev):
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   237
                if cfgpath:
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   238
                    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
   239
                                 % (name, path))
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   240
                return None
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   241
            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
   242
            return path
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   243
5117
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
   244
        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
   245
        oldmodule = ''
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   246
        trunk = getcfgpath('trunk', rev)
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   247
        tags = getcfgpath('tags', rev)
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   248
        branches = getcfgpath('branches', rev)
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   249
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   250
        # 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
   251
        # 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
   252
        if trunk:
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   253
            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
   254
            self.module += '/' + trunk
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   255
            lt = self.latest(self.module, self.last_changed)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   256
            self.head = self.revid(lt)
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   257
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   258
        # 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
   259
        self.heads = [self.head]
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   260
        self.tags = '%s/%s' % (oldmodule , (tags or 'tags'))
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   261
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   262
        # 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
   263
        if branches:
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   264
            rpath = self.url.strip('/')
5117
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
   265
            branchnames = svn.client.ls(rpath + '/' + branches, rev, False,
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   266
                                        self.ctx)
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   267
            for branch in branchnames.keys():
5854
8b95f598097c convert: separate trunk detection from branch layout detection
Edouard Gomez <ed.gomez@free.fr>
parents: 5842
diff changeset
   268
                module = '%s/%s/%s' % (oldmodule, branches, branch)
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   269
                brevnum = self.latest(module, self.last_changed)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   270
                brev = self.revid(brevnum, module)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   271
                self.ui.note('found branch %s at %d\n' % (branch, brevnum))
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   272
                self.heads.append(brev)
5462
91a522a69c13 convert: svn -- fix tags handling
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5461
diff changeset
   273
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   274
        return self.heads
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   275
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   276
    def getfile(self, file, rev):
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   277
        data, mode = self._getfile(file, rev)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   278
        self.modecache[(file, rev)] = mode
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   279
        return data
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   280
4957
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4949
diff changeset
   281
    def getmode(self, file, rev):
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   282
        return self.modecache[(file, rev)]
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   283
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   284
    def getchanges(self, rev):
5382
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   285
        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
   286
            return self._changescache[1]
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   287
        self._changescache = None
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   288
        self.modecache = {}
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   289
        (paths, parents) = self.paths[rev]
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   290
        files, copies = self.expandpaths(rev, paths, parents)
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   291
        files.sort()
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   292
        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
   293
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   294
        # 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
   295
        del self.paths[rev]
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   296
        return (files, copies)
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   297
5382
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   298
    def getchangedfiles(self, rev, i):
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   299
        changes = self.getchanges(rev)
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   300
        self._changescache = (rev, changes)
d7d395fb7cd5 convert_svn: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5373
diff changeset
   301
        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
   302
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   303
    def getcommit(self, rev):
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   304
        if rev not in self.commits:
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   305
            uuid, module, revnum = self.revsplit(rev)
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   306
            self.module = module
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   307
            self.reparent(module)
5875
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   308
            # We assume that:
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   309
            # - 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
   310
            # 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
   311
            # 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
   312
            # - 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
   313
            # 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
   314
            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
   315
            if revnum < stop:
f1504d3355bb convert: fetch less revisions when looking for a branch parent
Patrick Mezard <pmezard@gmail.com>
parents: 5873
diff changeset
   316
                stop = revnum + 1
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   317
            self._fetch_revisions(revnum, stop)
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   318
        commit = self.commits[rev]
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   319
        # 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
   320
        del self.commits[rev]
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   321
        return commit
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   322
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   323
    def gettags(self):
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   324
        tags = {}
4949
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   325
        start = self.revnum(self.head)
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   326
        try:
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   327
            for entry in get_log(self.url, [self.tags], 0, start):
4949
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   328
                orig_paths, revnum, author, date, message = entry
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   329
                for path in orig_paths:
5462
91a522a69c13 convert: svn -- fix tags handling
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5461
diff changeset
   330
                    if not path.startswith(self.tags+'/'):
4949
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   331
                        continue
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   332
                    ent = orig_paths[path]
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   333
                    source = ent.copyfrom_path
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   334
                    rev = ent.copyfrom_rev
5462
91a522a69c13 convert: svn -- fix tags handling
Kirill Smelkov <kirr@landau.phys.spbu.ru>
parents: 5461
diff changeset
   335
                    tag = path.split('/')[-1]
4949
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   336
                    tags[tag] = self.revid(rev, module=source)
5140
792c1d979097 Replace _ with inst for catching exceptions to not shadow gettext.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5139
diff changeset
   337
        except SubversionException, (inst, num):
4949
2f0f9528e77b convert/subversion: rehandle the no-tags case
Bryan O'Sullivan <bos@serpentine.com>
parents: 4946
diff changeset
   338
            self.ui.note('no tags found at revision %d\n' % start)
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
   339
        return tags
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   340
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   341
    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
   342
        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
   343
            return
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   344
        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
   345
            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
   346
                                  'a')
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   347
        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
   348
        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
   349
4840
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   350
    # -- helper functions --
a265fe42abe7 convert: svn code movement (no actual changes)
Brendan Cully <brendan@kublai.com>
parents: 4839
diff changeset
   351
4810
c2d529f288a1 convert: move some code into common init function
Brendan Cully <brendan@kublai.com>
parents: 4807
diff changeset
   352
    def revid(self, revnum, module=None):
4795
ea618c5934f3 convert: svn: get parent for branch creation events
Brendan Cully <brendan@kublai.com>
parents: 4794
diff changeset
   353
        if not module:
ea618c5934f3 convert: svn: get parent for branch creation events
Brendan Cully <brendan@kublai.com>
parents: 4794
diff changeset
   354
            module = self.module
5287
c6f932d3e0f6 Don't decode unicode strings.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5276
diff changeset
   355
        return u"svn:%s%s@%s" % (self.uuid, module.decode(self.encoding),
c6f932d3e0f6 Don't decode unicode strings.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5276
diff changeset
   356
                                 revnum)
4774
d305852a5ec8 convert: svn: add revnum() to convert rev to revnum
Brendan Cully <brendan@kublai.com>
parents: 4773
diff changeset
   357
d305852a5ec8 convert: svn: add revnum() to convert rev to revnum
Brendan Cully <brendan@kublai.com>
parents: 4773
diff changeset
   358
    def revnum(self, rev):
d305852a5ec8 convert: svn: add revnum() to convert rev to revnum
Brendan Cully <brendan@kublai.com>
parents: 4773
diff changeset
   359
        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
   360
4794
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
   361
    def revsplit(self, rev):
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
   362
        url, revnum = rev.encode(self.encoding).split('@', 1)
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
   363
        revnum = int(revnum)
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
   364
        parts = url.split('/', 1)
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
   365
        uuid = parts.pop(0)[4:]
4797
09dae950919f convert: svn: autodetect /branches, /tags, /trunk.
Brendan Cully <brendan@kublai.com>
parents: 4796
diff changeset
   366
        mod = ''
4794
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
   367
        if parts:
4797
09dae950919f convert: svn: autodetect /branches, /tags, /trunk.
Brendan Cully <brendan@kublai.com>
parents: 4796
diff changeset
   368
            mod = '/' + parts[0]
4794
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
   369
        return uuid, mod, revnum
1f10a6cccdb5 convert: add optional module argument to svn._fetch_revisions
Brendan Cully <brendan@kublai.com>
parents: 4793
diff changeset
   370
4790
c2ef09a35c53 convert: typo in svn.latest
Brendan Cully <brendan@kublai.com>
parents: 4789
diff changeset
   371
    def latest(self, path, stop=0):
4789
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   372
        'find the latest revision affecting path, up to stop'
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   373
        if not stop:
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   374
            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
   375
        try:
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   376
            self.reparent('')
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   377
            dirent = svn.ra.stat(self.ra, path.strip('/'), stop)
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   378
            self.reparent(self.module)
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   379
        except SubversionException:
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   380
            dirent = None
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   381
        if not dirent:
4925
2642726b61b6 convert/subversion.py: fix bad assumptions about SVN path naming
Bryan O'Sullivan <bos@serpentine.com>
parents: 4873
diff changeset
   382
            raise util.Abort('%s not found up to revision %d' % (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
   383
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   384
        return dirent.created_rev
c5dd8e184279 convert: svn: add function to get the latest revision touching a path
Brendan Cully <brendan@kublai.com>
parents: 4788
diff changeset
   385
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   386
    def get_blacklist(self):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   387
        """Avoid certain revision numbers.
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   388
        It is not uncommon for two nearby revisions to cancel each other
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   389
        out, e.g. 'I copied trunk into a subdirectory of itself instead
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   390
        of making a branch'. The converted repository is significantly
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   391
        smaller if we ignore such revisions."""
5276
694eb9ccb54d convert/subversion: Use util.set() instead of set() for python2.3 compatibility
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5250
diff changeset
   392
        self.blacklist = util.set()
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   393
        blacklist = self.blacklist
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   394
        for line in file("blacklist.txt", "r"):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   395
            if not line.startswith("#"):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   396
                try:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   397
                    svn_rev = int(line.strip())
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   398
                    blacklist.add(svn_rev)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   399
                except ValueError, e:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   400
                    pass # not an integer or a comment
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   401
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   402
    def is_blacklisted(self, svn_rev):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   403
        return svn_rev in self.blacklist
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   404
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   405
    def reparent(self, module):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   406
        svn_url = self.base + module
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   407
        self.ui.debug("reparent to %s\n" % svn_url.encode(self.encoding))
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   408
        svn.ra.reparent(self.ra, svn_url.encode(self.encoding))
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   409
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   410
    def expandpaths(self, rev, paths, parents):
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   411
        def get_entry_from_path(path, module=self.module):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   412
            # Given the repository url of this wc, say
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   413
            #   "http://server/plone/CMFPlone/branches/Plone-2_0-branch"
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   414
            # extract the "entry" portion (a relative path) from what
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   415
            # svn log --xml says, ie
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   416
            #   "/CMFPlone/branches/Plone-2_0-branch/tests/PloneTestCase.py"
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   417
            # that is to say "tests/PloneTestCase.py"
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   418
            if path.startswith(module):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   419
                relative = path[len(module):]
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   420
                if relative.startswith('/'):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   421
                    return relative[1:]
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   422
                else:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   423
                    return relative
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   424
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   425
            # The path is outside our tracked tree...
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   426
            self.ui.debug('%r is not under %r, ignoring\n' % (path, module))
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   427
            return None
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   428
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   429
        entries = []
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   430
        copyfrom = {} # Map of entrypath, revision for finding source of deleted revisions.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   431
        copies = {}
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   432
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   433
        new_module, revnum = self.revsplit(rev)[1:]
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   434
        if new_module != self.module:
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   435
            self.module = new_module
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   436
            self.reparent(self.module)
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5120
diff changeset
   437
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   438
        for path, ent in paths:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   439
            entrypath = get_entry_from_path(path, module=self.module)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   440
            entry = entrypath.decode(self.encoding)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   441
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   442
            kind = svn.ra.check_path(self.ra, entrypath, revnum)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   443
            if kind == svn.core.svn_node_file:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   444
                if ent.copyfrom_path:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   445
                    copyfrom_path = get_entry_from_path(ent.copyfrom_path)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   446
                    if copyfrom_path:
5841
07ca22a72dcc svn: fix copy exception
"Shun-ichi GOTO" <shunichi.goto@gmail.com>
parents: 5832
diff changeset
   447
                        self.ui.debug("Copied to %s from %s@%s\n" %
07ca22a72dcc svn: fix copy exception
"Shun-ichi GOTO" <shunichi.goto@gmail.com>
parents: 5832
diff changeset
   448
                                      (entrypath, copyfrom_path,
07ca22a72dcc svn: fix copy exception
"Shun-ichi GOTO" <shunichi.goto@gmail.com>
parents: 5832
diff changeset
   449
                                       ent.copyfrom_rev))
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   450
                        # It's probably important for hg that the source
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   451
                        # exists in the revision's parent, not just the
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   452
                        # ent.copyfrom_rev
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   453
                        fromkind = svn.ra.check_path(self.ra, copyfrom_path, ent.copyfrom_rev)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   454
                        if fromkind != 0:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   455
                            copies[self.recode(entry)] = self.recode(copyfrom_path)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   456
                entries.append(self.recode(entry))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   457
            elif kind == 0: # gone, but had better be a deleted *file*
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   458
                self.ui.debug("gone from %s\n" % ent.copyfrom_rev)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   459
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   460
                # if a branch is created but entries are removed in the same
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   461
                # changeset, get the right fromrev
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   462
                # parents cannot be empty here, you cannot remove things from
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   463
                # a root revision.
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   464
                uuid, old_module, fromrev = self.revsplit(parents[0])
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   465
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   466
                basepath = old_module + "/" + get_entry_from_path(path, module=self.module)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   467
                entrypath = old_module + "/" + get_entry_from_path(path, module=self.module)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   468
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   469
                def lookup_parts(p):
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   470
                    rc = None
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   471
                    parts = p.split("/")
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   472
                    for i in range(len(parts)):
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   473
                        part = "/".join(parts[:i])
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   474
                        info = part, copyfrom.get(part, None)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   475
                        if info[1] is not None:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   476
                            self.ui.debug("Found parent directory %s\n" % info[1])
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   477
                            rc = info
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   478
                    return rc
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   479
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   480
                self.ui.debug("base, entry %s %s\n" % (basepath, entrypath))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   481
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   482
                frompath, froment = lookup_parts(entrypath) or (None, revnum - 1)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   483
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   484
                # need to remove fragment from lookup_parts and replace with copyfrom_path
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   485
                if frompath is not None:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   486
                    self.ui.debug("munge-o-matic\n")
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   487
                    self.ui.debug(entrypath + '\n')
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   488
                    self.ui.debug(entrypath[len(frompath):] + '\n')
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   489
                    entrypath = froment.copyfrom_path + entrypath[len(frompath):]
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   490
                    fromrev = froment.copyfrom_rev
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   491
                    self.ui.debug("Info: %s %s %s %s\n" % (frompath, froment, ent, entrypath))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   492
5880
b32a0596b2d7 convert: fix invalid svn.ra.check_path() call (issue 771)
Patrick Mezard <pmezard@gmail.com>
parents: 5617
diff changeset
   493
                # We can avoid the reparent calls if the module has not changed
b32a0596b2d7 convert: fix invalid svn.ra.check_path() call (issue 771)
Patrick Mezard <pmezard@gmail.com>
parents: 5617
diff changeset
   494
                # but it probably does not worth the pain.
b32a0596b2d7 convert: fix invalid svn.ra.check_path() call (issue 771)
Patrick Mezard <pmezard@gmail.com>
parents: 5617
diff changeset
   495
                self.reparent('')
b32a0596b2d7 convert: fix invalid svn.ra.check_path() call (issue 771)
Patrick Mezard <pmezard@gmail.com>
parents: 5617
diff changeset
   496
                fromkind = svn.ra.check_path(self.ra, entrypath.strip('/'), fromrev)
b32a0596b2d7 convert: fix invalid svn.ra.check_path() call (issue 771)
Patrick Mezard <pmezard@gmail.com>
parents: 5617
diff changeset
   497
                self.reparent(self.module)
b32a0596b2d7 convert: fix invalid svn.ra.check_path() call (issue 771)
Patrick Mezard <pmezard@gmail.com>
parents: 5617
diff changeset
   498
                
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   499
                if fromkind == svn.core.svn_node_file:   # a deleted file
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   500
                    entries.append(self.recode(entry))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   501
                elif fromkind == svn.core.svn_node_dir:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   502
                    # print "Deleted/moved non-file:", revnum, path, ent
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   503
                    # children = self._find_children(path, revnum - 1)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   504
                    # print "find children %s@%d from %d action %s" % (path, revnum, ent.copyfrom_rev, ent.action)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   505
                    # Sometimes this is tricky. For example: in
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   506
                    # The Subversion Repository revision 6940 a dir
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   507
                    # was copied and one of its files was deleted
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   508
                    # from the new location in the same commit. This
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   509
                    # code can't deal with that yet.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   510
                    if ent.action == 'C':
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   511
                        children = self._find_children(path, fromrev)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   512
                    else:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   513
                        oroot = entrypath.strip('/')
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   514
                        nroot = path.strip('/')
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   515
                        children = self._find_children(oroot, fromrev)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   516
                        children = [s.replace(oroot,nroot) for s in children]
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   517
                    # Mark all [files, not directories] as deleted.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   518
                    for child in children:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   519
                        # Can we move a child directory and its
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   520
                        # parent in the same commit? (probably can). Could
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   521
                        # cause problems if instead of revnum -1,
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   522
                        # we have to look in (copyfrom_path, revnum - 1)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   523
                        entrypath = get_entry_from_path("/" + child, module=old_module)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   524
                        if entrypath:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   525
                            entry = self.recode(entrypath.decode(self.encoding))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   526
                            if entry in copies:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   527
                                # deleted file within a copy
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   528
                                del copies[entry]
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   529
                            else:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   530
                                entries.append(entry)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   531
                else:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   532
                    self.ui.debug('unknown path in revision %d: %s\n' % \
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   533
                                  (revnum, path))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   534
            elif kind == svn.core.svn_node_dir:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   535
                # Should probably synthesize normal file entries
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   536
                # and handle as above to clean up copy/rename handling.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   537
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   538
                # If the directory just had a prop change,
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   539
                # 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
   540
                if ent.action == 'M':
0d583ade5817 convert: don't scan directories on property changes
Patrick Mezard <pmezard@gmail.com>
parents: 5854
diff changeset
   541
                    continue
0d583ade5817 convert: don't scan directories on property changes
Patrick Mezard <pmezard@gmail.com>
parents: 5854
diff changeset
   542
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   543
                # Also this could create duplicate entries. Not sure
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   544
                # whether this will matter. Maybe should make entries a set.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   545
                # print "Changed directory", revnum, path, ent.action, ent.copyfrom_path, ent.copyfrom_rev
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   546
                # This will fail if a directory was copied
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   547
                # from another branch and then some of its files
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   548
                # were deleted in the same transaction.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   549
                children = self._find_children(path, revnum)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   550
                children.sort()
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   551
                for child in children:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   552
                    # Can we move a child directory and its
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   553
                    # parent in the same commit? (probably can). Could
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   554
                    # cause problems if instead of revnum -1,
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   555
                    # we have to look in (copyfrom_path, revnum - 1)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   556
                    entrypath = get_entry_from_path("/" + child, module=self.module)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   557
                    # print child, self.module, entrypath
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   558
                    if entrypath:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   559
                        # Need to filter out directories here...
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   560
                        kind = svn.ra.check_path(self.ra, entrypath, revnum)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   561
                        if kind != svn.core.svn_node_dir:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   562
                            entries.append(self.recode(entrypath))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   563
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   564
                # Copies here (must copy all from source)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   565
                # Probably not a real problem for us if
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   566
                # source does not exist
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   567
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   568
                # Can do this with the copy command "hg copy"
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   569
                # if ent.copyfrom_path:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   570
                #     copyfrom_entry = get_entry_from_path(ent.copyfrom_path.decode(self.encoding),
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   571
                #             module=self.module)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   572
                #     copyto_entry = entrypath
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   573
                #
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   574
                #     print "copy directory", copyfrom_entry, 'to', copyto_entry
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   575
                #
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   576
                #     copies.append((copyfrom_entry, copyto_entry))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   577
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   578
                if ent.copyfrom_path:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   579
                    copyfrom_path = ent.copyfrom_path.decode(self.encoding)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   580
                    copyfrom_entry = get_entry_from_path(copyfrom_path, module=self.module)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   581
                    if copyfrom_entry:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   582
                        copyfrom[path] = ent
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   583
                        self.ui.debug("mark %s came from %s\n" % (path, copyfrom[path]))
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   584
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   585
                        # Good, /probably/ a regular copy. Really should check
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   586
                        # to see whether the parent revision actually contains
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   587
                        # the directory in question.
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   588
                        children = self._find_children(self.recode(copyfrom_path), ent.copyfrom_rev)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   589
                        children.sort()
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   590
                        for child in children:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   591
                            entrypath = get_entry_from_path("/" + child, module=self.module)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   592
                            if entrypath:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   593
                                entry = entrypath.decode(self.encoding)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   594
                                # print "COPY COPY From", copyfrom_entry, entry
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   595
                                copyto_path = path + entry[len(copyfrom_entry):]
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   596
                                copyto_entry =  get_entry_from_path(copyto_path, module=self.module)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   597
                                # print "COPY", entry, "COPY To", copyto_entry
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   598
                                copies[self.recode(copyto_entry)] = self.recode(entry)
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   599
                                # copy from quux splort/quuxfile
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   600
5883
a893610f6f0c convert: enforce svn_source.getchanges() files unicity
Patrick Mezard <pmezard@gmail.com>
parents: 5880
diff changeset
   601
        return (util.unique(entries), copies)
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   602
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   603
    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
   604
        if from_revnum < to_revnum:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   605
            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
   606
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
   607
        self.child_cset = None
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
   608
        def parselogentry(orig_paths, revnum, author, date, message):
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   609
            """Return the parsed commit object or None, and True if 
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   610
            the revision is a branch root.
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   611
            """
4946
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
   612
            self.ui.debug("parsing revision %d (%d changes)\n" %
e8f4e40f285a convert/subversion: work around memory leak in svn's python bindings
Bryan O'Sullivan <bos@serpentine.com>
parents: 4944
diff changeset
   613
                          (revnum, len(orig_paths)))
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
   614
4810
c2d529f288a1 convert: move some code into common init function
Brendan Cully <brendan@kublai.com>
parents: 4807
diff changeset
   615
            rev = self.revid(revnum)
4837
4cdbaa885d8a convert: svn: some improvements in memory usage
Brendan Cully <brendan@kublai.com>
parents: 4814
diff changeset
   616
            # 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
   617
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   618
            if (rev in self.commits or revnum < to_revnum):
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   619
                return None, False
4837
4cdbaa885d8a convert: svn: some improvements in memory usage
Brendan Cully <brendan@kublai.com>
parents: 4814
diff changeset
   620
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   621
            parents = []
5119
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   622
            # check whether this revision is the start of a branch
5250
585471802a01 convert: svn: check for branch movement in any log entry, not just the first.
Brendan Cully <brendan@kublai.com>
parents: 5145
diff changeset
   623
            if self.module in orig_paths:
585471802a01 convert: svn: check for branch movement in any log entry, not just the first.
Brendan Cully <brendan@kublai.com>
parents: 5145
diff changeset
   624
                ent = orig_paths[self.module]
5119
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   625
                if ent.copyfrom_path:
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   626
                    # ent.copyfrom_rev may not be the actual last revision
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   627
                    prev = self.latest(ent.copyfrom_path, ent.copyfrom_rev)
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   628
                    parents = [self.revid(prev, ent.copyfrom_path)]
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   629
                    self.ui.note('found parent of branch %s at %d: %s\n' % \
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   630
                                     (self.module, prev, ent.copyfrom_path))
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   631
                else:
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   632
                    self.ui.debug("No copyfrom path, don't know what to do.\n")
4cef0b93969d convert: svn: hoist up branch creation check
Brendan Cully <brendan@kublai.com>
parents: 5118
diff changeset
   633
5250
585471802a01 convert: svn: check for branch movement in any log entry, not just the first.
Brendan Cully <brendan@kublai.com>
parents: 5145
diff changeset
   634
            orig_paths = orig_paths.items()
585471802a01 convert: svn: check for branch movement in any log entry, not just the first.
Brendan Cully <brendan@kublai.com>
parents: 5145
diff changeset
   635
            orig_paths.sort()
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   636
            paths = []
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   637
            # filter out unrelated paths
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
   638
            for path, ent in orig_paths:
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   639
                if not path.startswith(self.module):
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
   640
                    self.ui.debug("boring@%s: %s\n" % (revnum, path))
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
   641
                    continue
5120
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   642
                paths.append((path, ent))
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   643
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
   644
            # 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
   645
            # 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
   646
            # '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
   647
            date = util.parsedate(date[:19] + " UTC", ["%Y-%m-%dT%H:%M:%S"])
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   648
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
   649
            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
   650
            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
   651
            try:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   652
                branch = self.module.split("/")[-1]
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   653
                if branch == 'trunk':
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   654
                    branch = ''
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   655
            except IndexError:
514c06098e9c convert: svn: pull up path to file expansion code into separate function.
Brendan Cully <brendan@kublai.com>
parents: 5119
diff changeset
   656
                branch = None
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   657
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
   658
            cset = commit(author=author,
4957
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4949
diff changeset
   659
                          date=util.datestr(date),
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4949
diff changeset
   660
                          desc=log,
4795
ea618c5934f3 convert: svn: get parent for branch creation events
Brendan Cully <brendan@kublai.com>
parents: 4794
diff changeset
   661
                          parents=parents,
4873
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4848
diff changeset
   662
                          branch=branch,
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4848
diff changeset
   663
                          rev=rev.encode('utf-8'))
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
   664
4796
26857a6f9dd0 convert: svn: pull out broken batching code, add alpha tags support
Brendan Cully <brendan@kublai.com>
parents: 4795
diff changeset
   665
            self.commits[rev] = cset
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   666
            # 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
   667
            # commit object. Both will be updated below.
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   668
            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
   669
            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
   670
                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
   671
            self.child_cset = cset
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   672
            return cset, len(parents) > 0
4796
26857a6f9dd0 convert: svn: pull out broken batching code, add alpha tags support
Brendan Cully <brendan@kublai.com>
parents: 4795
diff changeset
   673
4940
961379b2c586 convert/subversion: reduce memory usage by filtering early
Bryan O'Sullivan <bos@serpentine.com>
parents: 4927
diff changeset
   674
        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
   675
                     (self.module, from_revnum, to_revnum))
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   676
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   677
        try:
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   678
            firstcset = None
5873
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   679
            stream = get_log(self.url, [self.module], from_revnum, to_revnum)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   680
            try:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   681
                for entry in stream:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   682
                    paths, revnum, author, date, message = entry
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   683
                    if self.is_blacklisted(revnum):
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   684
                        self.ui.note('skipping blacklisted revision %d\n' 
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   685
                                     % revnum)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   686
                        continue
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   687
                    if paths is None:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   688
                        self.ui.debug('revision %d has no entries\n' % revnum)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   689
                        continue
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   690
                    cset, branched = parselogentry(paths, revnum, author, 
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   691
                                                   date, message)
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   692
                    if cset:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   693
                        firstcset = cset
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   694
                    if branched:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   695
                        break
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   696
            finally:
ecb4eb0cbff2 convert: make svn revision iterator interruptible
Patrick Mezard <pmezard@gmail.com>
parents: 5872
diff changeset
   697
                stream.close()
5871
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   698
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   699
            if firstcset and not firstcset.parents:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   700
                # 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
   701
                # 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
   702
                # revision now, if any.
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   703
                try:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   704
                    firstrevnum = self.revnum(firstcset.rev)
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   705
                    if firstrevnum > 1:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   706
                        latest = self.latest(self.module, firstrevnum - 1)
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   707
                        firstcset.parents.append(self.revid(latest))
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   708
                except util.Abort:
c1244685425a convert: fix parents of last fetched svn revision
Patrick Mezard <pmezard@gmail.com>
parents: 5870
diff changeset
   709
                    pass
5140
792c1d979097 Replace _ with inst for catching exceptions to not shadow gettext.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5139
diff changeset
   710
        except SubversionException, (inst, num):
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   711
            if num == svn.core.SVN_ERR_FS_NO_SUCH_REVISION:
4957
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4949
diff changeset
   712
                raise NoSuchRevision(branch=self,
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   713
                    revision="Revision number %d" % to_revnum)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   714
            raise
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   715
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   716
    def _getfile(self, file, rev):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   717
        io = StringIO()
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   718
        # TODO: ra.get_file transmits the whole file instead of diffs.
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   719
        mode = ''
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   720
        try:
5872
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   721
            new_module, revnum = self.revsplit(rev)[1:]
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   722
            if self.module != new_module:
7d4149cccc5d convert: fix cross-branches subversion revisions handling
Patrick Mezard <pmezard@gmail.com>
parents: 5871
diff changeset
   723
                self.module = new_module
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   724
                self.reparent(self.module)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   725
            info = svn.ra.get_file(self.ra, file, revnum, io)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   726
            if isinstance(info, list):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   727
                info = info[-1]
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   728
            mode = ("svn:executable" in info) and 'x' or ''
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   729
            mode = ("svn:special" in info) and 'l' or mode
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   730
        except SubversionException, e:
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   731
            notfound = (svn.core.SVN_ERR_FS_NOT_FOUND,
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   732
                svn.core.SVN_ERR_RA_DAV_PATH_NOT_FOUND)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   733
            if e.apr_err in notfound: # File not found
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   734
                raise IOError()
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   735
            raise
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   736
        data = io.getvalue()
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   737
        if mode == 'l':
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   738
            link_prefix = "link "
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   739
            if data.startswith(link_prefix):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   740
                data = data[len(link_prefix):]
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   741
        return data, mode
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   742
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   743
    def _find_children(self, path, revnum):
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
   744
        path = path.strip('/')
4765
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents:
diff changeset
   745
        pool = Pool()
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
   746
        rpath = '/'.join([self.base, path]).strip('/')
5117
c89ed1f27e78 convert: svn: add helper function for optrevs
Brendan Cully <brendan@kublai.com>
parents: 5114
diff changeset
   747
        return ['%s/%s' % (path, x) for x in svn.client.ls(rpath, optrev(revnum), True, self.ctx, pool).keys()]
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   748
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   749
pre_revprop_change = '''#!/bin/sh
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   750
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   751
REPOS="$1"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   752
REV="$2"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   753
USER="$3"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   754
PROPNAME="$4"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   755
ACTION="$5"
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   756
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   757
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
   758
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
   759
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
   760
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   761
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
   762
exit 1
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   763
'''
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   764
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   765
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
   766
    commit_re = re.compile(r'Committed revision (\d+).', re.M)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   767
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   768
    def prerun(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   769
        if self.wc:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   770
            os.chdir(self.wc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   771
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   772
    def postrun(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   773
        if self.wc:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   774
            os.chdir(self.cwd)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   775
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   776
    def join(self, name):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   777
        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
   778
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   779
    def revmapfile(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   780
        return self.join('hg-shamap')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   781
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   782
    def authorfile(self):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   783
        return self.join('hg-authormap')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   784
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   785
    def __init__(self, ui, path):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   786
        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
   787
        commandline.__init__(self, ui, 'svn')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   788
        self.delete = []
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   789
        self.setexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   790
        self.delexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   791
        self.copies = []
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   792
        self.wc = None
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   793
        self.cwd = os.getcwd()
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   794
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   795
        path = os.path.realpath(path)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   796
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   797
        created = False
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   798
        if os.path.isfile(os.path.join(path, '.svn', 'entries')):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   799
            self.wc = path
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   800
            self.run0('update')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   801
        else:
5535
7501ef26402b convert: fix svn file:// URL generation under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5528
diff changeset
   802
            wcpath = os.path.join(os.getcwd(), os.path.basename(path) + '-wc')
7501ef26402b convert: fix svn file:// URL generation under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5528
diff changeset
   803
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   804
            if os.path.isdir(os.path.dirname(path)):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   805
                if not os.path.exists(os.path.join(path, 'db', 'fs-type')):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   806
                    ui.status(_('initializing svn repo %r\n') %
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   807
                              os.path.basename(path))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   808
                    commandline(ui, 'svnadmin').run0('create', path)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   809
                    created = path
5842
111ed8c871bf Use util.normpath() instead of direct path string operation.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 5841
diff changeset
   810
                path = util.normpath(path)
5535
7501ef26402b convert: fix svn file:// URL generation under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5528
diff changeset
   811
                if not path.startswith('/'):
7501ef26402b convert: fix svn file:// URL generation under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 5528
diff changeset
   812
                    path = '/' + path
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   813
                path = 'file://' + path
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5705
diff changeset
   814
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   815
            ui.status(_('initializing svn wc %r\n') % os.path.basename(wcpath))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   816
            self.run0('checkout', path, wcpath)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   817
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   818
            self.wc = wcpath
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   819
        self.opener = util.opener(self.wc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   820
        self.wopener = util.opener(self.wc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   821
        self.childmap = mapfile(ui, self.join('hg-childmap'))
5536
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   822
        self.is_exec = util.checkexec(self.wc) and util.is_exec or None
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   823
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   824
        if created:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   825
            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
   826
            fp = open(hook, 'w')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   827
            fp.write(pre_revprop_change)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   828
            fp.close()
5705
4e400863c5ac convert/svn: use util.set_flags
Matt Mackall <mpm@selenic.com>
parents: 5698
diff changeset
   829
            util.set_flags(hook, "x")
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   830
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   831
        xport = transport.SvnRaTransport(url=geturl(path))
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   832
        self.uuid = svn.ra.get_uuid(xport.ra)
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   833
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   834
    def wjoin(self, *names):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   835
        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
   836
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   837
    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
   838
        if 'l' in flags:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   839
            self.wopener.symlink(data, filename)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   840
        else:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   841
            try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   842
                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
   843
                    os.unlink(filename)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   844
            except OSError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   845
                pass
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   846
            self.wopener(filename, 'w').write(data)
5536
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   847
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   848
            if self.is_exec:
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   849
                was_exec = self.is_exec(self.wjoin(filename))
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   850
            else:
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   851
                # On filesystems not supporting execute-bit, there is no way
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   852
                # to know if it is set but asking subversion. Setting it
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   853
                # systematically is just as expensive and much simpler.
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   854
                was_exec = 'x' not in flags
fdee5d614fcc convert: force svn:executable when execute-bit is not supported
Patrick Mezard <pmezard@gmail.com>
parents: 5535
diff changeset
   855
5705
4e400863c5ac convert/svn: use util.set_flags
Matt Mackall <mpm@selenic.com>
parents: 5698
diff changeset
   856
            util.set_flags(self.wjoin(filename), flags)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   857
            if was_exec:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   858
                if 'x' not in flags:
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   859
                    self.delexec.append(filename)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   860
            else:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   861
                if '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
   862
                    self.setexec.append(filename)
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   863
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   864
    def delfile(self, name):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   865
        self.delete.append(name)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   866
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   867
    def copyfile(self, source, dest):
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   868
        self.copies.append([source, dest])
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   869
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   870
    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
   871
        # 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
   872
        # 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
   873
        # 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
   874
        wdest = self.wjoin(dest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   875
        exists = os.path.exists(wdest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   876
        if exists:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   877
            fd, tempname = tempfile.mkstemp(
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   878
                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
   879
            os.close(fd)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   880
            os.unlink(tempname)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   881
            os.rename(wdest, tempname)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   882
        try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   883
            self.run0('copy', source, dest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   884
        finally:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   885
            if exists:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   886
                try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   887
                    os.unlink(wdest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   888
                except OSError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   889
                    pass
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   890
                os.rename(tempname, wdest)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   891
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   892
    def dirs_of(self, files):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   893
        dirs = set()
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   894
        for f in files:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   895
            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
   896
                dirs.add(f)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   897
            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
   898
                dirs.add(f[:i])
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   899
        return dirs
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   900
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   901
    def add_dirs(self, files):
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   902
        add_dirs = [d for d in self.dirs_of(files)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   903
                    if not os.path.exists(self.wjoin(d, '.svn', 'entries'))]
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   904
        if add_dirs:
5537
e01c748cb632 convert: add directories to subversion from root to leaves
Patrick Mezard <pmezard@gmail.com>
parents: 5536
diff changeset
   905
            add_dirs.sort()
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
   906
            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
   907
        return add_dirs
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   908
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   909
    def add_files(self, files):
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   910
        if files:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
   911
            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
   912
        return files
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5705
diff changeset
   913
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   914
    def tidy_dirs(self, names):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   915
        dirs = list(self.dirs_of(names))
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   916
        dirs.sort(reverse=True)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   917
        deleted = []
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   918
        for d in dirs:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   919
            wd = self.wjoin(d)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   920
            if os.listdir(wd) == '.svn':
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   921
                self.run0('delete', d)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   922
                deleted.append(d)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   923
        return deleted
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   924
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   925
    def addchild(self, parent, child):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   926
        self.childmap[parent] = child
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   927
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   928
    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
   929
        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
   930
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   931
    def putcommit(self, files, parents, commit):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   932
        for parent in parents:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   933
            try:
5554
2147a734dcf9 convert: tell the source repository when a rev has been converted
Bryan O'Sullivan <bos@serpentine.com>
parents: 5537
diff changeset
   934
                return self.revid(self.childmap[parent])
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   935
            except KeyError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   936
                pass
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   937
        entries = set(self.delete)
5698
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   938
        files = util.frozenset(files)
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   939
        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
   940
        if self.copies:
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   941
            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
   942
                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
   943
            self.copies = []
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   944
        if self.delete:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
   945
            self.xargs(self.delete, 'delete')
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   946
            self.delete = []
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   947
        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
   948
        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
   949
        if self.delexec:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
   950
            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
   951
            self.delexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   952
        if self.setexec:
5832
2192ed187319 convert: add commandline.xargs(), use it in svn_sink class
Maxim Dounin <mdounin@mdounin.ru>
parents: 5806
diff changeset
   953
            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
   954
            self.setexec = []
b63ef7b1441c convert: svn-sink: copy and set properties after adding dirs/files
Maxim Dounin <mdounin@mdounin.ru>
parents: 5618
diff changeset
   955
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   956
        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
   957
        fp = os.fdopen(fd, 'w')
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   958
        fp.write(commit.desc)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   959
        fp.close()
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   960
        try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   961
            output = self.run0('commit',
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   962
                               username=util.shortuser(commit.author),
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   963
                               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
   964
                               encoding='utf-8')
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   965
            try:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   966
                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
   967
            except AttributeError:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   968
                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
   969
                self.ui.warn(output)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   970
                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
   971
            if commit.rev:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   972
                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
   973
                         revprop=True, revision=rev)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   974
            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
   975
                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
   976
                         revprop=True, revision=rev)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   977
            for parent in parents:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   978
                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
   979
            return self.revid(rev)
5513
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   980
        finally:
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   981
            os.unlink(messagefile)
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   982
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   983
    def puttags(self, tags):
f0c58fd4b798 convert: add support for Subversion as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5511
diff changeset
   984
        self.ui.warn(_('XXX TAGS NOT IMPLEMENTED YET\n'))