hgext/convert/cvs.py
author Brendan Cully <brendan@kublai.com>
Wed, 15 Aug 2007 14:38:18 -0700
changeset 5182 7e05bdeee7de
parent 5146 7106f4899aa0
child 5308 9400d677efc7
permissions -rw-r--r--
convert: raise Abort instead of NoRepo when CVS pserver auth fails. At this point we know the source is CVS, so we should not go through the rest of the converters.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4536
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
4536
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
4447
1b75e0eff532 document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents: 4114
diff changeset
     5
4536
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
4447
1b75e0eff532 document conversion interface
Daniel Holth <dholth@fastmail.fm>
parents: 4114
diff changeset
     7
4448
af013ae3ca10 use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents: 4447
diff changeset
     8
class convert_cvs(converter_source):
4760
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
     9
    def __init__(self, ui, path, rev=None):
4807
15a3cbfc6568 convert: call superclass init from engine init functions
Brendan Cully <brendan@kublai.com>
parents: 4762
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: 4762
diff changeset
    11
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    12
        cvs = os.path.join(path, "CVS")
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    13
        if not os.path.exists(cvs):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
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: 3939
diff changeset
    15
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    16
        self.changeset = {}
3954
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
    17
        self.files = {}
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    18
        self.tags = {}
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    19
        self.lastbranch = {}
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    20
        self.parent = {}
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    21
        self.socket = None
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
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: 3939
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: 3939
diff changeset
    24
        self.encoding = locale.getpreferredencoding()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    25
        self._parse()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    26
        self._connect()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    27
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    28
    def _parse(self):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    29
        if self.changeset:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    30
            return
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    31
4760
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    32
        maxrev = 0
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
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: 4759
diff changeset
    34
        if self.rev:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    35
            # TODO: handle tags
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    36
            try:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    37
                # patchset number?
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    38
                maxrev = int(self.rev)
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    39
            except ValueError:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    40
                try:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    41
                    # date
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    42
                    util.parsedate(self.rev, ['%Y/%m/%d %H:%M:%S'])
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    43
                    cmd = "%s -d '1970/01/01 00:00:01' -d '%s'" % (cmd, self.rev)
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    44
                except util.Abort:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    45
                    raise util.Abort('revision %s is not a patchset number or date' % self.rev)
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    46
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    47
        d = os.getcwd()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    48
        try:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    49
            os.chdir(self.path)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    50
            id = None
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    51
            state = 0
4760
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    52
            for l in os.popen(cmd):
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    53
                if state == 0: # header
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    54
                    if l.startswith("PatchSet"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    55
                        id = l[9:-2]
4760
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    56
                        if maxrev and int(id) > maxrev:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
    57
                            state = 3
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    58
                    elif l.startswith("Date"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    59
                        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: 3939
diff changeset
    60
                        date = util.datestr(date)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    61
                    elif l.startswith("Branch"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    62
                        branch = l[8:-1]
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
    63
                        self.parent[id] = self.lastbranch.get(branch, 'bad')
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    64
                        self.lastbranch[branch] = id
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    65
                    elif l.startswith("Ancestor branch"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    66
                        ancestor = l[17:-1]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    67
                        self.parent[id] = self.lastbranch[ancestor]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    68
                    elif l.startswith("Author"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    69
                        author = self.recode(l[8:-1])
4698
30e826bd8ed1 convert: handle new cvsps with Tags: and multiple tags.
Eric Hopper <hopper@omnifarious.org>
parents: 4536
diff changeset
    70
                    elif l.startswith("Tag:") or l.startswith("Tags:"):
30e826bd8ed1 convert: handle new cvsps with Tags: and multiple tags.
Eric Hopper <hopper@omnifarious.org>
parents: 4536
diff changeset
    71
                        t = l[l.index(':')+1:]
30e826bd8ed1 convert: handle new cvsps with Tags: and multiple tags.
Eric Hopper <hopper@omnifarious.org>
parents: 4536
diff changeset
    72
                        t = [ut.strip() for ut in t.split(',')]
30e826bd8ed1 convert: handle new cvsps with Tags: and multiple tags.
Eric Hopper <hopper@omnifarious.org>
parents: 4536
diff changeset
    73
                        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: 4536
diff changeset
    74
                            self.tags.update(dict.fromkeys(t, id))
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    75
                    elif l.startswith("Log:"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    76
                        state = 1
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    77
                        log = ""
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    78
                elif state == 1: # log
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    79
                    if l == "Members: \n":
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    80
                        files = {}
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    81
                        log = self.recode(log[:-1])
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    82
                        state = 2
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    83
                    else:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    84
                        log += l
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    85
                elif state == 2:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    86
                    if l == "\n": #
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    87
                        state = 0
3954
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
    88
                        p = [self.parent[id]]
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
    89
                        if id == "1":
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
    90
                            p = []
4518
3e4aa4c9efe4 convert: map CVS HEAD to default branch
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4516
diff changeset
    91
                        if branch == "HEAD":
3e4aa4c9efe4 convert: map CVS HEAD to default branch
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4516
diff changeset
    92
                            branch = ""
3954
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
    93
                        c = commit(author=author, date=date, parents=p,
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
    94
                                   desc=log, branch=branch)
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
    95
                        self.changeset[id] = c
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
    96
                        self.files[id] = files
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
    97
                    else:
4515
86a66cce9566 Fixed python2.3 incompatibility (rsplit) in cvs code of convert extension
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4513
diff changeset
    98
                        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
    99
                        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
   100
                        rev = l[colon+1:-2]
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   101
                        rev = rev.split("->")[1]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   102
                        files[file] = rev
4760
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
   103
                elif state == 3:
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4759
diff changeset
   104
                    continue
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   105
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   106
            self.heads = self.lastbranch.values()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   107
        finally:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   108
            os.chdir(d)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   109
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   110
    def _connect(self):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   111
        root = self.cvsroot
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   112
        conntype = None
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   113
        user, host = None, None
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   114
        cmd = ['cvs', 'server']
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   115
4513
ac2fe196ac9b Turns convert.py into a real extension
Edouard Gomez <ed.gomez@free.fr>
parents: 4512
diff changeset
   116
        self.ui.status("connecting to %s\n" % root)
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   117
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   118
        if root.startswith(":pserver:"):
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   119
            root = root[9:]
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   120
            m = re.match(r'(?:(.*?)(?::(.*?))?@)?([^:\/]*)(?::(\d*))?(.*)',
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   121
                         root)
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   122
            if m:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   123
                conntype = "pserver"
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   124
                user, passw, serv, port, root = m.groups()
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   125
                if not user:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   126
                    user = "anonymous"
5082
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   127
                if not port:
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   128
                    port = 2401
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   129
                else:
5082
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   130
                    port = int(port)
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   131
                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
   132
                format1 = ":pserver:%s@%s:%d%s" % (user, serv, port, root)
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   133
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   134
                if not passw:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   135
                    passw = "A"
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   136
                    pf = open(os.path.join(os.environ["HOME"], ".cvspass"))
5082
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   137
                    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
   138
                        part1, part2 = line.split(' ', 1)
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   139
                        if part1 == '/1':
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   140
                            # /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
   141
                            part1, part2 = part2.split(' ', 1)
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   142
                            format = format1
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   143
                        else:
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   144
                            # :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
   145
                            format = format0
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   146
                        if part1 == format:
dc2e512cb89a CVS import: Support new-style .cvspass-file format.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4698
diff changeset
   147
                            passw = part2
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   148
                            break
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   149
                    pf.close()
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   150
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   151
                sck = socket.socket()
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   152
                sck.connect((serv, port))
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   153
                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
   154
                                    "END AUTH REQUEST", ""]))
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   155
                if sck.recv(128) != "I LOVE YOU\n":
5182
7e05bdeee7de convert: raise Abort instead of NoRepo when CVS pserver auth fails.
Brendan Cully <brendan@kublai.com>
parents: 5146
diff changeset
   156
                    raise util.Abort("CVS pserver authentication failed")
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   157
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   158
                self.writep = self.readp = sck.makefile('r+')
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   159
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   160
        if not conntype and root.startswith(":local:"):
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   161
            conntype = "local"
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   162
            root = root[7:]
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   163
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   164
        if not conntype:
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   165
            # :ext:user@host/home/user/path/to/cvsroot
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   166
            if root.startswith(":ext:"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   167
                root = root[5:]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   168
            m = re.match(r'(?:([^@:/]+)@)?([^:/]+):?(.*)', root)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   169
            if not m:
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   170
                conntype = "local"
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   171
            else:
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   172
                conntype = "rsh"
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   173
                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: 3939
diff changeset
   174
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   175
        if conntype != "pserver":
4516
96d8a56d4ef9 Removed trailing whitespace and tabs from python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4515
diff changeset
   176
            if conntype == "rsh":
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   177
                rsh = os.environ.get("CVS_RSH" or "rsh")
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   178
                if user:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   179
                    cmd = [rsh, '-l', user, host] + cmd
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   180
                else:
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   181
                    cmd = [rsh, host] + cmd
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   182
4047
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   183
            self.writep, self.readp = os.popen2(cmd)
705d0792dbf2 add pserver support to convert_repo
csaba.henk@creo.hu
parents: 4006
diff changeset
   184
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   185
        self.realroot = root
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   186
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   187
        self.writep.write("Root %s\n" % root)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   188
        self.writep.write("Valid-responses ok error Valid-requests Mode"
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   189
                          " M Mbinary E Checked-in Created Updated"
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   190
                          " Merged Removed\n")
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   191
        self.writep.write("valid-requests\n")
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   192
        self.writep.flush()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   193
        r = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   194
        if not r.startswith("Valid-requests"):
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   195
            raise util.Abort("server sucks")
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   196
        if "UseUnchanged" in r:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   197
            self.writep.write("UseUnchanged\n")
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   198
            self.writep.flush()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   199
            r = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   200
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   201
    def getheads(self):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   202
        return self.heads
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   203
3956
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   204
    def _getfile(self, name, rev):
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   205
        if rev.endswith("(DEAD)"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   206
            raise IOError
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   207
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   208
        args = ("-N -P -kk -r %s --" % rev).split()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   209
        args.append(os.path.join(self.cvsrepo, name))
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   210
        for x in args:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   211
            self.writep.write("Argument %s\n" % x)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   212
        self.writep.write("Directory .\n%s\nco\n" % self.realroot)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   213
        self.writep.flush()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   214
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   215
        data = ""
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   216
        while 1:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   217
            line = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   218
            if line.startswith("Created ") or line.startswith("Updated "):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   219
                self.readp.readline() # path
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   220
                self.readp.readline() # entries
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   221
                mode = self.readp.readline()[:-1]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   222
                count = int(self.readp.readline()[:-1])
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   223
                data = self.readp.read(count)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   224
            elif line.startswith(" "):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   225
                data += line[1:]
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   226
            elif line.startswith("M "):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   227
                pass
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   228
            elif line.startswith("Mbinary "):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   229
                count = int(self.readp.readline()[:-1])
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   230
                data = self.readp.read(count)
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   231
            else:
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   232
                if line == "ok\n":
4082
6b2909e84203 convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents: 4062
diff changeset
   233
                    return (data, "x" in mode and "x" or "")
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   234
                elif line.startswith("E "):
4513
ac2fe196ac9b Turns convert.py into a real extension
Edouard Gomez <ed.gomez@free.fr>
parents: 4512
diff changeset
   235
                    self.ui.warn("cvs server: %s\n" % line[2:])
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   236
                elif line.startswith("Remove"):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   237
                    l = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   238
                    l = self.readp.readline()
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   239
                    if l != "ok\n":
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   240
                        raise util.Abort("unknown CVS response: %s" % l)
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   241
                else:
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
   242
                    raise util.Abort("unknown CVS response: %s" % line)
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   243
3956
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   244
    def getfile(self, file, rev):
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   245
        data, mode = self._getfile(file, rev)
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   246
        self.modecache[(file, rev)] = mode
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   247
        return data
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   248
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   249
    def getmode(self, file, rev):
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   250
        return self.modecache[(file, rev)]
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   251
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   252
    def getchanges(self, rev):
3956
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   253
        self.modecache = {}
3954
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
   254
        files = self.files[rev]
3956
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   255
        cl = files.items()
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   256
        cl.sort()
5121
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 4810
diff changeset
   257
        return (cl, {})
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   258
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   259
    def getcommit(self, rev):
3954
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3953
diff changeset
   260
        return self.changeset[rev]
3953
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   261
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   262
    def gettags(self):
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3939
diff changeset
   263
        return self.tags