hgext/convert/cvs.py
author Matt Mackall <mpm@selenic.com>
Thu, 11 Oct 2007 00:46:54 -0500
changeset 5451 0a43875677b1
parent 5381 6874368120dc
permissions -rw-r--r--
revlog: break up compression of large deltas Python's zlib apparently makes an internal copy of strings passed to compress(). To avoid this, compress strings 1M at a time, then join them at the end if the result would be smaller than the original. For initial commits of large but compressible files, this cuts peak memory usage nearly in half.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4534
cc9b79216a76 Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents: 4532
diff changeset
     1
# CVS conversion code inspired by hg-cvs-import and git-cvsimport
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4515
diff changeset
     2
4534
cc9b79216a76 Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents: 4532
diff changeset
     3
import os, locale, re, socket
cc9b79216a76 Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents: 4532
diff changeset
     4
from mercurial import util
4446
1b75e0eff532 document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents: 4114
diff changeset
     5
4534
cc9b79216a76 Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents: 4532
diff changeset
     6
from common import NoRepo, commit, converter_source
4446
1b75e0eff532 document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents: 4114
diff changeset
     7
4447
af013ae3ca10 use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents: 4446
diff changeset
     8
class convert_cvs(converter_source):
4753
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
     9
    def __init__(self, ui, path, rev=None):
4806
15a3cbfc6568 convert: call superclass init from engine init functions
Brendan Cully <brendan@kublai.com>
parents: 4755
diff changeset
    10
        super(convert_cvs, self).__init__(ui, path, rev=rev)
15a3cbfc6568 convert: call superclass init from engine init functions
Brendan Cully <brendan@kublai.com>
parents: 4755
diff changeset
    11
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    12
        cvs = os.path.join(path, "CVS")
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    13
        if not os.path.exists(cvs):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    14
            raise NoRepo("couldn't open CVS repo %s" % path)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    15
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    16
        self.changeset = {}
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    17
        self.files = {}
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    18
        self.tags = {}
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    19
        self.lastbranch = {}
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    20
        self.parent = {}
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    21
        self.socket = None
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    22
        self.cvsroot = file(os.path.join(cvs, "Root")).read()[:-1]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    23
        self.cvsrepo = file(os.path.join(cvs, "Repository")).read()[:-1]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    24
        self.encoding = locale.getpreferredencoding()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    25
        self._parse()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    26
        self._connect()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    27
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    28
    def _parse(self):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    29
        if self.changeset:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    30
            return
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    31
4753
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    32
        maxrev = 0
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    33
        cmd = 'cvsps -A -u --cvs-direct -q'
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    34
        if self.rev:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    35
            # TODO: handle tags
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    36
            try:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    37
                # patchset number?
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    38
                maxrev = int(self.rev)
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    39
            except ValueError:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    40
                try:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    41
                    # date
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    42
                    util.parsedate(self.rev, ['%Y/%m/%d %H:%M:%S'])
5308
9400d677efc7 Merge with crew-stable
Patrick Mezard <pmezard@gmail.com>
parents: 5173 5306
diff changeset
    43
                    cmd = '%s -d "1970/01/01 00:00:01" -d "%s"' % (cmd, self.rev)
4753
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    44
                except util.Abort:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    45
                    raise util.Abort('revision %s is not a patchset number or date' % self.rev)
5308
9400d677efc7 Merge with crew-stable
Patrick Mezard <pmezard@gmail.com>
parents: 5173 5306
diff changeset
    46
        cmd += " 2>&1"
4753
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    47
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    48
        d = os.getcwd()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    49
        try:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    50
            os.chdir(self.path)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    51
            id = None
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    52
            state = 0
4753
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    53
            for l in os.popen(cmd):
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    54
                if state == 0: # header
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    55
                    if l.startswith("PatchSet"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    56
                        id = l[9:-2]
4753
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    57
                        if maxrev and int(id) > maxrev:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    58
                            state = 3
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    59
                    elif l.startswith("Date"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    60
                        date = util.parsedate(l[6:-1], ["%Y/%m/%d %H:%M:%S"])
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    61
                        date = util.datestr(date)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    62
                    elif l.startswith("Branch"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    63
                        branch = l[8:-1]
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
    64
                        self.parent[id] = self.lastbranch.get(branch, 'bad')
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    65
                        self.lastbranch[branch] = id
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    66
                    elif l.startswith("Ancestor branch"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    67
                        ancestor = l[17:-1]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    68
                        self.parent[id] = self.lastbranch[ancestor]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    69
                    elif l.startswith("Author"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    70
                        author = self.recode(l[8:-1])
4698
30e826bd8ed1 convert: handle new cvsps with Tags: and multiple tags.
Eric Hopper <hopper@omnifarious.org>
parents: 4534
diff changeset
    71
                    elif l.startswith("Tag:") or l.startswith("Tags:"):
30e826bd8ed1 convert: handle new cvsps with Tags: and multiple tags.
Eric Hopper <hopper@omnifarious.org>
parents: 4534
diff changeset
    72
                        t = l[l.index(':')+1:]
30e826bd8ed1 convert: handle new cvsps with Tags: and multiple tags.
Eric Hopper <hopper@omnifarious.org>
parents: 4534
diff changeset
    73
                        t = [ut.strip() for ut in t.split(',')]
30e826bd8ed1 convert: handle new cvsps with Tags: and multiple tags.
Eric Hopper <hopper@omnifarious.org>
parents: 4534
diff changeset
    74
                        if (len(t) > 1) or (t[0] and (t[0] != "(none)")):
30e826bd8ed1 convert: handle new cvsps with Tags: and multiple tags.
Eric Hopper <hopper@omnifarious.org>
parents: 4534
diff changeset
    75
                            self.tags.update(dict.fromkeys(t, id))
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    76
                    elif l.startswith("Log:"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    77
                        state = 1
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    78
                        log = ""
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    79
                elif state == 1: # log
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    80
                    if l == "Members: \n":
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    81
                        files = {}
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    82
                        log = self.recode(log[:-1])
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    83
                        state = 2
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    84
                    else:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    85
                        log += l
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    86
                elif state == 2:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    87
                    if l == "\n": #
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    88
                        state = 0
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    89
                        p = [self.parent[id]]
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    90
                        if id == "1":
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    91
                            p = []
4518
3e4aa4c9efe4 convert: map CVS HEAD to default branch
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4516
diff changeset
    92
                        if branch == "HEAD":
3e4aa4c9efe4 convert: map CVS HEAD to default branch
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4516
diff changeset
    93
                            branch = ""
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    94
                        c = commit(author=author, date=date, parents=p,
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    95
                                   desc=log, branch=branch)
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    96
                        self.changeset[id] = c
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    97
                        self.files[id] = files
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    98
                    else:
4515
86a66cce9566 Fixed python2.3 incompatibility (rsplit) in cvs code of convert extension
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4513
diff changeset
    99
                        colon = l.rfind(':')
86a66cce9566 Fixed python2.3 incompatibility (rsplit) in cvs code of convert extension
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4513
diff changeset
   100
                        file = l[1:colon]
86a66cce9566 Fixed python2.3 incompatibility (rsplit) in cvs code of convert extension
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4513
diff changeset
   101
                        rev = l[colon+1:-2]
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   102
                        rev = rev.split("->")[1]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   103
                        files[file] = rev
4753
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
   104
                elif state == 3:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
   105
                    continue
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   106
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   107
            self.heads = self.lastbranch.values()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   108
        finally:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   109
            os.chdir(d)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   110
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   111
    def _connect(self):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   112
        root = self.cvsroot
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   113
        conntype = None
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   114
        user, host = None, None
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   115
        cmd = ['cvs', 'server']
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   116
4513
ac2fe196ac9b Turns convert.py into a real extension
Edouard Gomez <ed.gomez@free.fr>
parents: 4512
diff changeset
   117
        self.ui.status("connecting to %s\n" % root)
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   118
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   119
        if root.startswith(":pserver:"):
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   120
            root = root[9:]
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   121
            m = re.match(r'(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?(.*)',
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   122
                         root)
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   123
            if m:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   124
                conntype = "pserver"
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   125
                user, passw, serv, port, root = m.groups()
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   126
                if not user:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   127
                    user = "anonymous"
5120
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   128
                if not port:
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   129
                    port = 2401
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   130
                else:
5120
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   131
                    port = int(port)
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   132
                format0 = ":pserver:%s@%s:%s" % (user, serv, root)
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   133
                format1 = ":pserver:%s@%s:%d%s" % (user, serv, port, root)
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   134
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   135
                if not passw:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   136
                    passw = "A"
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   137
                    pf = open(os.path.join(os.environ["HOME"], ".cvspass"))
5120
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   138
                    for line in pf.read().splitlines():
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   139
                        part1, part2 = line.split(' ', 1)
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   140
                        if part1 == '/1':
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   141
                            # /1 :pserver:user@example.com:2401/cvsroot/foo Ah<Z
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   142
                            part1, part2 = part2.split(' ', 1)
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   143
                            format = format1
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   144
                        else:
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   145
                            # :pserver:user@example.com:/cvsroot/foo Ah<Z
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   146
                            format = format0
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   147
                        if part1 == format:
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   148
                            passw = part2
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   149
                            break
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   150
                    pf.close()
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   151
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   152
                sck = socket.socket()
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   153
                sck.connect((serv, port))
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   154
                sck.send("\n".join(["BEGIN AUTH REQUEST", root, user, passw,
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   155
                                    "END AUTH REQUEST", ""]))
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   156
                if sck.recv(128) != "I LOVE YOU\n":
5173
7e05bdeee7de convert: raise Abort instead of NoRepo when CVS pserver auth fails.
Brendan Cully <brendan@kublai.com>
parents: 5121
diff changeset
   157
                    raise util.Abort("CVS pserver authentication failed")
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   158
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   159
                self.writep = self.readp = sck.makefile('r+')
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   160
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   161
        if not conntype and root.startswith(":local:"):
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   162
            conntype = "local"
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   163
            root = root[7:]
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   164
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   165
        if not conntype:
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   166
            # :ext:user@host/home/user/path/to/cvsroot
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   167
            if root.startswith(":ext:"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   168
                root = root[5:]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   169
            m = re.match(r'(?:([^@:/]+)@)?([^:/]+):?(.*)', root)
5304
b85f7cc133cc convert: avoid interpreting Windows path as CVS connection strings.
Patrick Mezard <pmezard@gmail.com>
parents: 5303
diff changeset
   170
            # Do not take Windows path "c:\foo\bar" for a connection strings
b85f7cc133cc convert: avoid interpreting Windows path as CVS connection strings.
Patrick Mezard <pmezard@gmail.com>
parents: 5303
diff changeset
   171
            if os.path.isdir(root) or not m:
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   172
                conntype = "local"
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   173
            else:
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   174
                conntype = "rsh"
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   175
                user, host, root = m.group(1), m.group(2), m.group(3)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   176
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   177
        if conntype != "pserver":
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4515
diff changeset
   178
            if conntype == "rsh":
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   179
                rsh = os.environ.get("CVS_RSH" or "rsh")
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   180
                if user:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   181
                    cmd = [rsh, '-l', user, host] + cmd
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   182
                else:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   183
                    cmd = [rsh, host] + cmd
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   184
5303
a76c61679b71 convert: call popen2 in binary mode, with a command string.
Patrick Mezard <pmezard@gmail.com>
parents: 5120
diff changeset
   185
            # popen2 does not support argument lists under Windows
a76c61679b71 convert: call popen2 in binary mode, with a command string.
Patrick Mezard <pmezard@gmail.com>
parents: 5120
diff changeset
   186
            cmd = [util.shellquote(arg) for arg in cmd]
a76c61679b71 convert: call popen2 in binary mode, with a command string.
Patrick Mezard <pmezard@gmail.com>
parents: 5120
diff changeset
   187
            cmd = util.quotecommand(' '.join(cmd))
a76c61679b71 convert: call popen2 in binary mode, with a command string.
Patrick Mezard <pmezard@gmail.com>
parents: 5120
diff changeset
   188
            self.writep, self.readp = os.popen2(cmd, 'b')
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   189
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   190
        self.realroot = root
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   191
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   192
        self.writep.write("Root %s\n" % root)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   193
        self.writep.write("Valid-responses ok error Valid-requests Mode"
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   194
                          " M Mbinary E Checked-in Created Updated"
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   195
                          " Merged Removed\n")
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   196
        self.writep.write("valid-requests\n")
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   197
        self.writep.flush()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   198
        r = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   199
        if not r.startswith("Valid-requests"):
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   200
            raise util.Abort("server sucks")
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   201
        if "UseUnchanged" in r:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   202
            self.writep.write("UseUnchanged\n")
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   203
            self.writep.flush()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   204
            r = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   205
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   206
    def getheads(self):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   207
        return self.heads
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   208
3957
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   209
    def _getfile(self, name, rev):
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   210
        if rev.endswith("(DEAD)"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   211
            raise IOError
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   212
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   213
        args = ("-N -P -kk -r %s --" % rev).split()
5305
87348cdce88c convert: fix remote cvs file paths separator
Patrick Mezard <pmezard@gmail.com>
parents: 5304
diff changeset
   214
        args.append(self.cvsrepo + '/' + name)
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   215
        for x in args:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   216
            self.writep.write("Argument %s\n" % x)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   217
        self.writep.write("Directory .\n%s\nco\n" % self.realroot)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   218
        self.writep.flush()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   219
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   220
        data = ""
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   221
        while 1:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   222
            line = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   223
            if line.startswith("Created ") or line.startswith("Updated "):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   224
                self.readp.readline() # path
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   225
                self.readp.readline() # entries
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   226
                mode = self.readp.readline()[:-1]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   227
                count = int(self.readp.readline()[:-1])
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   228
                data = self.readp.read(count)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   229
            elif line.startswith(" "):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   230
                data += line[1:]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   231
            elif line.startswith("M "):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   232
                pass
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   233
            elif line.startswith("Mbinary "):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   234
                count = int(self.readp.readline()[:-1])
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   235
                data = self.readp.read(count)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   236
            else:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   237
                if line == "ok\n":
4082
6b2909e84203 convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents: 4062
diff changeset
   238
                    return (data, "x" in mode and "x" or "")
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   239
                elif line.startswith("E "):
4513
ac2fe196ac9b Turns convert.py into a real extension
Edouard Gomez <ed.gomez@free.fr>
parents: 4512
diff changeset
   240
                    self.ui.warn("cvs server: %s\n" % line[2:])
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   241
                elif line.startswith("Remove"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   242
                    l = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   243
                    l = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   244
                    if l != "ok\n":
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   245
                        raise util.Abort("unknown CVS response: %s" % l)
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   246
                else:
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   247
                    raise util.Abort("unknown CVS response: %s" % line)
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   248
3957
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   249
    def getfile(self, file, rev):
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   250
        data, mode = self._getfile(file, rev)
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   251
        self.modecache[(file, rev)] = mode
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   252
        return data
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   253
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   254
    def getmode(self, file, rev):
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   255
        return self.modecache[(file, rev)]
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   256
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   257
    def getchanges(self, rev):
3957
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   258
        self.modecache = {}
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   259
        files = self.files[rev]
3957
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
   260
        cl = files.items()
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   261
        cl.sort()
5076
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 4809
diff changeset
   262
        return (cl, {})
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   263
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   264
    def getcommit(self, rev):
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   265
        return self.changeset[rev]
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   266
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   267
    def gettags(self):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
   268
        return self.tags
5381
6874368120dc convert_cvs: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5308
diff changeset
   269
6874368120dc convert_cvs: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5308
diff changeset
   270
    def getchangedfiles(self, rev, i):
6874368120dc convert_cvs: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5308
diff changeset
   271
        files = self.files[rev].keys()
6874368120dc convert_cvs: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5308
diff changeset
   272
        files.sort()
6874368120dc convert_cvs: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5308
diff changeset
   273
        return files
6874368120dc convert_cvs: add --filemap support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5308
diff changeset
   274