hgext/convert/p4.py
author Boris Feld <boris.feld@octobus.net>
Thu, 21 Jun 2018 23:53:43 +0100
changeset 38511 879cbdde63df
parent 37120 a8a902d7176e
child 41537 fc09aafd3c36
permissions -rw-r--r--
revlog: do inclusive descendant testing (API) In many other places, a revision is considered a descendant of itself. We update the behavior of `revlog.descendant()` to match this. (for example. `revlog.isancestor` does inclusive testing). No tests break, so it seems safe to do so. This will make it easier to use a more efficient implementation in a later changeset.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
     1
# Perforce source for convert extension.
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
     2
#
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
     3
# Copyright 2009, Frank Kingswood <frank@kingswood-consulting.co.uk>
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9476
diff changeset
     6
# GNU General Public License version 2 or any later version.
28371
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
     7
from __future__ import absolute_import
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
     8
28371
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
     9
import marshal
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    10
import re
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    11
29205
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 28371
diff changeset
    12
from mercurial.i18n import _
28371
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    13
from mercurial import (
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    14
    error,
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    15
    util,
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    16
)
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
    17
from mercurial.utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
    18
    dateutil,
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    19
    procutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
    20
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
    21
)
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    22
28371
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    23
from . import common
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    24
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    25
def loaditer(f):
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    26
    "Yield the dictionary objects generated by p4"
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    27
    try:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    28
        while True:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    29
            d = marshal.load(f)
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    30
            if not d:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    31
                break
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    32
            yield d
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    33
    except EOFError:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    34
        pass
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    35
25788
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    36
def decodefilename(filename):
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    37
    """Perforce escapes special characters @, #, *, or %
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    38
    with %40, %23, %2A, or %25 respectively
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    39
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 31590
diff changeset
    40
    >>> decodefilename(b'portable-net45%252Bnetcore45%252Bwp8%252BMonoAndroid')
25788
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    41
    'portable-net45%2Bnetcore45%2Bwp8%2BMonoAndroid'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 31590
diff changeset
    42
    >>> decodefilename(b'//Depot/Directory/%2525/%2523/%23%40.%2A')
25788
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    43
    '//Depot/Directory/%25/%23/#@.*'
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    44
    """
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    45
    replacements = [('%2A', '*'), ('%23', '#'), ('%40', '@'), ('%25', '%')]
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    46
    for k, v in replacements:
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    47
        filename = filename.replace(k, v)
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    48
    return filename
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
    49
28371
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    50
class p4_source(common.converter_source):
35176
671aba341d90 convert: save an indicator of the repo type for sources and sinks
Matt Harbison <matt_harbison@yahoo.com>
parents: 35036
diff changeset
    51
    def __init__(self, ui, repotype, path, revs=None):
35036
281214150561 convert: avoid wrong lfconvert defaults by moving configitems to core
Matt Harbison <matt_harbison@yahoo.com>
parents: 34503
diff changeset
    52
        # avoid import cycle
281214150561 convert: avoid wrong lfconvert defaults by moving configitems to core
Matt Harbison <matt_harbison@yahoo.com>
parents: 34503
diff changeset
    53
        from . import convcmd
281214150561 convert: avoid wrong lfconvert defaults by moving configitems to core
Matt Harbison <matt_harbison@yahoo.com>
parents: 34503
diff changeset
    54
35176
671aba341d90 convert: save an indicator of the repo type for sources and sinks
Matt Harbison <matt_harbison@yahoo.com>
parents: 35036
diff changeset
    55
        super(p4_source, self).__init__(ui, repotype, path, revs=revs)
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    56
8829
ce4b92f5cea7 convert: Make P4 conversion cope with keywords, binary files and symbolic links.
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents: 8225
diff changeset
    57
        if "/" in path and not path.startswith('//'):
28371
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    58
            raise common.NoRepo(_('%s does not look like a P4 repository') %
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    59
                                path)
7973
db3a68fd9387 convert: attempt to check repo type before checking for tool
Matt Mackall <mpm@selenic.com>
parents: 7905
diff changeset
    60
28371
630f5f04bc74 convert: p4 use absolute_import
timeless <timeless@mozdev.org>
parents: 26779
diff changeset
    61
        common.checktool('p4', abort=False)
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    62
30601
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    63
        self.revmap = {}
35036
281214150561 convert: avoid wrong lfconvert defaults by moving configitems to core
Matt Harbison <matt_harbison@yahoo.com>
parents: 34503
diff changeset
    64
        self.encoding = self.ui.config('convert', 'p4.encoding',
281214150561 convert: avoid wrong lfconvert defaults by moving configitems to core
Matt Harbison <matt_harbison@yahoo.com>
parents: 34503
diff changeset
    65
                                       convcmd.orig_encoding)
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    66
        self.re_type = re.compile(
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    67
            "([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)"
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    68
            "(\+\w+)?$")
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    69
        self.re_keywords = re.compile(
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    70
            r"\$(Id|Header|Date|DateTime|Change|File|Revision|Author)"
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    71
            r":[^$\n]*\$")
8829
ce4b92f5cea7 convert: Make P4 conversion cope with keywords, binary files and symbolic links.
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents: 8225
diff changeset
    72
        self.re_keywords_old = re.compile("\$(Id|Header):[^$\n]*\$")
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    73
25748
baea47cafe75 convert: add support for specifying multiple revs
Durham Goode <durham@fb.com>
parents: 24395
diff changeset
    74
        if revs and len(revs) > 1:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25884
diff changeset
    75
            raise error.Abort(_("p4 source does not support specifying "
25748
baea47cafe75 convert: add support for specifying multiple revs
Durham Goode <durham@fb.com>
parents: 24395
diff changeset
    76
                               "multiple revisions"))
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    77
30601
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    78
    def setrevmap(self, revmap):
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    79
        """Sets the parsed revmap dictionary.
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    80
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    81
        Revmap stores mappings from a source revision to a target revision.
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    82
        It is set in convertcmd.convert and provided by the user as a file
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    83
        on the commandline.
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    84
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    85
        Revisions in the map are considered beeing present in the
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    86
        repository and ignored during _parse(). This allows for incremental
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    87
        imports if a revmap is provided.
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    88
        """
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    89
        self.revmap = revmap
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
    90
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    91
    def _parse_view(self, path):
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    92
        "Read changes affecting the path"
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    93
        cmd = 'p4 -G changes -s submitted %s' % procutil.shellquote(path)
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
    94
        stdout = procutil.popen(cmd, mode='rb')
30629
e92776c00ffd convert: use return value in parse_view() instead of manipulating state
David Soria Parra <davidsp@fb.com>
parents: 30617
diff changeset
    95
        p4changes = {}
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    96
        for d in loaditer(stdout):
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    97
            c = d.get("change", None)
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
    98
            if c:
30629
e92776c00ffd convert: use return value in parse_view() instead of manipulating state
David Soria Parra <davidsp@fb.com>
parents: 30617
diff changeset
    99
                p4changes[c] = True
e92776c00ffd convert: use return value in parse_view() instead of manipulating state
David Soria Parra <davidsp@fb.com>
parents: 30617
diff changeset
   100
        return p4changes
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   101
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   102
    def _parse(self, ui, path):
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   103
        "Prepare list of P4 filenames and revisions to import"
30631
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   104
        p4changes = {}
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   105
        changeset = {}
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   106
        files_map = {}
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   107
        copies_map = {}
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   108
        localname = {}
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   109
        depotname = {}
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   110
        heads = []
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   111
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   112
        ui.status(_('reading p4 views\n'))
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   113
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   114
        # read client spec or view
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   115
        if "/" in path:
30631
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   116
            p4changes.update(self._parse_view(path))
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   117
            if path.startswith("//") and path.endswith("/..."):
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   118
                views = {path[:-3]:""}
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   119
            else:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   120
                views = {"//": ""}
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   121
        else:
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   122
            cmd = 'p4 -G client -o %s' % procutil.shellquote(path)
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   123
            clientspec = marshal.load(procutil.popen(cmd, mode='rb'))
7869
bc027d72c289 cleanup: remove all trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7823
diff changeset
   124
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   125
            views = {}
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   126
            for client in clientspec:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   127
                if client.startswith("View"):
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   128
                    sview, cview = clientspec[client].split()
30631
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   129
                    p4changes.update(self._parse_view(sview))
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   130
                    if sview.endswith("...") and cview.endswith("..."):
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   131
                        sview = sview[:-3]
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   132
                        cview = cview[:-3]
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   133
                    cview = cview[2:]
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   134
                    cview = cview[cview.find("/") + 1:]
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   135
                    views[sview] = cview
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   136
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   137
        # list of changes that affect our source files
30631
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   138
        p4changes = p4changes.keys()
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   139
        p4changes.sort(key=int)
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   140
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   141
        # list with depot pathnames, longest first
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   142
        vieworder = views.keys()
9039
8761863c3118 p4: simplify sort key
Martin Geisler <mg@lazybytes.net>
parents: 8843
diff changeset
   143
        vieworder.sort(key=len, reverse=True)
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   144
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   145
        # handle revision limiting
34175
b1d94bc61c79 configitems: register the 'convert.p4.startrev' config
Boris Feld <boris.feld@octobus.net>
parents: 34131
diff changeset
   146
        startrev = self.ui.config('convert', 'p4.startrev')
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   147
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   148
        # now read the full changelists to get the list of file revisions
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   149
        ui.status(_('collecting p4 changelists\n'))
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   150
        lastid = None
30631
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   151
        for change in p4changes:
30597
fa2d2c8ac398 convert: don't use long list comprehensions
David Soria Parra <davidsp@fb.com>
parents: 29205
diff changeset
   152
            if startrev and int(change) < int(startrev):
fa2d2c8ac398 convert: don't use long list comprehensions
David Soria Parra <davidsp@fb.com>
parents: 29205
diff changeset
   153
                continue
fa2d2c8ac398 convert: don't use long list comprehensions
David Soria Parra <davidsp@fb.com>
parents: 29205
diff changeset
   154
            if self.revs and int(change) > int(self.revs[0]):
fa2d2c8ac398 convert: don't use long list comprehensions
David Soria Parra <davidsp@fb.com>
parents: 29205
diff changeset
   155
                continue
30601
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
   156
            if change in self.revmap:
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
   157
                # Ignore already present revisions, but set the parent pointer.
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
   158
                lastid = change
d47a01bf0059 convert: allow passing in a revmap
David Soria Parra <davidsp@fb.com>
parents: 30600
diff changeset
   159
                continue
30597
fa2d2c8ac398 convert: don't use long list comprehensions
David Soria Parra <davidsp@fb.com>
parents: 29205
diff changeset
   160
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   161
            if lastid:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   162
                parents = [lastid]
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   163
            else:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   164
                parents = []
7869
bc027d72c289 cleanup: remove all trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7823
diff changeset
   165
30603
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   166
            d = self._fetch_revision(change)
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   167
            c = self._construct_commit(d, parents)
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   168
31590
78ac8acfc4bd convert: fix the handling of empty changlist descriptions in P4
David Soria Parra <davidsp@fb.com>
parents: 30632
diff changeset
   169
            descarr = c.desc.splitlines(True)
78ac8acfc4bd convert: fix the handling of empty changlist descriptions in P4
David Soria Parra <davidsp@fb.com>
parents: 30632
diff changeset
   170
            if len(descarr) > 0:
78ac8acfc4bd convert: fix the handling of empty changlist descriptions in P4
David Soria Parra <davidsp@fb.com>
parents: 30632
diff changeset
   171
                shortdesc = descarr[0].rstrip('\r\n')
78ac8acfc4bd convert: fix the handling of empty changlist descriptions in P4
David Soria Parra <davidsp@fb.com>
parents: 30632
diff changeset
   172
            else:
78ac8acfc4bd convert: fix the handling of empty changlist descriptions in P4
David Soria Parra <davidsp@fb.com>
parents: 30632
diff changeset
   173
                shortdesc = '**empty changelist description**'
78ac8acfc4bd convert: fix the handling of empty changlist descriptions in P4
David Soria Parra <davidsp@fb.com>
parents: 30632
diff changeset
   174
30603
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   175
            t = '%s %s' % (c.rev, repr(shortdesc)[1:-1])
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
   176
            ui.status(stringutil.ellipsis(t, 80) + '\n')
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   177
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   178
            files = []
25751
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   179
            copies = {}
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   180
            copiedfiles = []
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   181
            i = 0
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   182
            while ("depotFile%d" % i) in d and ("rev%d" % i) in d:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   183
                oldname = d["depotFile%d" % i]
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   184
                filename = None
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   185
                for v in vieworder:
25776
809c3e4a9e31 convert: ignore case changes in vieworder for Perforce
Eugene Baranov <eug.baranov@gmail.com>
parents: 25775
diff changeset
   186
                    if oldname.lower().startswith(v.lower()):
25788
a36fd0993522 convert: unescape Perforce-escaped special characters in filenames
Eugene Baranov <eug.baranov@gmail.com>
parents: 25776
diff changeset
   187
                        filename = decodefilename(views[v] + oldname[len(v):])
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   188
                        break
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   189
                if filename:
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   190
                    files.append((filename, d["rev%d" % i]))
30631
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   191
                    depotname[filename] = oldname
25751
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   192
                    if (d.get("action%d" % i) == "move/add"):
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   193
                        copiedfiles.append(filename)
30630
3830f8806094 convert: move localname state to function scope
David Soria Parra <davidsp@fb.com>
parents: 30629
diff changeset
   194
                    localname[oldname] = filename
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   195
                i += 1
25751
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   196
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   197
            # Collect information about copied files
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   198
            for filename in copiedfiles:
30631
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   199
                oldname = depotname[filename]
25751
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   200
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   201
                flcmd = 'p4 -G filelog %s' \
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   202
                      % procutil.shellquote(oldname)
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   203
                flstdout = procutil.popen(flcmd, mode='rb')
25751
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   204
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   205
                copiedfilename = None
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   206
                for d in loaditer(flstdout):
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   207
                    copiedoldname = None
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   208
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   209
                    i = 0
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   210
                    while ("change%d" % i) in d:
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   211
                        if (d["change%d" % i] == change and
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   212
                            d["action%d" % i] == "move/add"):
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   213
                            j = 0
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   214
                            while ("file%d,%d" % (i, j)) in d:
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   215
                                if d["how%d,%d" % (i, j)] == "moved from":
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   216
                                    copiedoldname = d["file%d,%d" % (i, j)]
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   217
                                    break
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   218
                                j += 1
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   219
                        i += 1
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   220
30630
3830f8806094 convert: move localname state to function scope
David Soria Parra <davidsp@fb.com>
parents: 30629
diff changeset
   221
                    if copiedoldname and copiedoldname in localname:
3830f8806094 convert: move localname state to function scope
David Soria Parra <davidsp@fb.com>
parents: 30629
diff changeset
   222
                        copiedfilename = localname[copiedoldname]
25751
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   223
                        break
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   224
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   225
                if copiedfilename:
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   226
                    copies[filename] = copiedfilename
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   227
                else:
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   228
                    ui.warn(_("cannot find source for copied file: %s@%s\n")
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   229
                            % (filename, change))
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   230
30631
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   231
            changeset[change] = c
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   232
            files_map[change] = files
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   233
            copies_map[change] = copies
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   234
            lastid = change
7869
bc027d72c289 cleanup: remove all trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7823
diff changeset
   235
30631
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   236
        if lastid and len(changeset) > 0:
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   237
            heads = [lastid]
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   238
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   239
        return {
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   240
            'changeset': changeset,
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   241
            'files': files_map,
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   242
            'copies': copies_map,
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   243
            'heads': heads,
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   244
            'depotname': depotname,
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   245
        }
c2be48e56d59 convert: return calculated values from parse() instead of manpulating state
David Soria Parra <davidsp@fb.com>
parents: 30630
diff changeset
   246
30632
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   247
    @util.propertycache
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   248
    def _parse_once(self):
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   249
        return self._parse(self.ui, self.path)
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   250
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   251
    @util.propertycache
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   252
    def copies(self):
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   253
        return self._parse_once['copies']
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   254
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   255
    @util.propertycache
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   256
    def files(self):
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   257
        return self._parse_once['files']
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   258
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   259
    @util.propertycache
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   260
    def changeset(self):
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   261
        return self._parse_once['changeset']
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   262
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   263
    @util.propertycache
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   264
    def heads(self):
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   265
        return self._parse_once['heads']
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   266
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   267
    @util.propertycache
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   268
    def depotname(self):
1d0e4832e616 convert: parse perforce data on-demand
David Soria Parra <davidsp@fb.com>
parents: 30631
diff changeset
   269
        return self._parse_once['depotname']
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   270
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   271
    def getheads(self):
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   272
        return self.heads
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   273
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   274
    def getfile(self, name, rev):
11348
ad0a334eef16 p4: fix long line and bad spacing around %
Martin Geisler <mg@aragost.com>
parents: 11347
diff changeset
   275
        cmd = 'p4 -G print %s' \
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   276
            % procutil.shellquote("%s#%s" % (self.depotname[name], rev))
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   277
25775
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   278
        lasterror = None
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   279
        while True:
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   280
            stdout = procutil.popen(cmd, mode='rb')
25775
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   281
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   282
            mode = None
25882
97a9f7602014 convert: when getting file from Perforce concatenate data at the end
Eugene Baranov <eug.baranov@gmail.com>
parents: 25805
diff changeset
   283
            contents = []
25775
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   284
            keywords = None
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   285
25775
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   286
            for d in loaditer(stdout):
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   287
                code = d["code"]
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   288
                data = d.get("data")
8829
ce4b92f5cea7 convert: Make P4 conversion cope with keywords, binary files and symbolic links.
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents: 8225
diff changeset
   289
25775
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   290
                if code == "error":
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   291
                    # if this is the first time error happened
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   292
                    # re-attempt getting the file
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   293
                    if not lasterror:
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   294
                        lasterror = IOError(d["generic"], data)
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   295
                        # this will exit inner-most for-loop
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   296
                        break
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   297
                    else:
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   298
                        raise lasterror
8843
eb7b247a98ea kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8829
diff changeset
   299
25775
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   300
                elif code == "stat":
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   301
                    action = d.get("action")
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   302
                    if action in ["purge", "delete", "move/delete"]:
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   303
                        return None, None
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   304
                    p4type = self.re_type.match(d["type"])
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   305
                    if p4type:
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   306
                        mode = ""
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   307
                        flags = ((p4type.group(1) or "")
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   308
                               + (p4type.group(3) or ""))
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   309
                        if "x" in flags:
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   310
                            mode = "x"
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   311
                        if p4type.group(2) == "symlink":
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   312
                            mode = "l"
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   313
                        if "ko" in flags:
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   314
                            keywords = self.re_keywords_old
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   315
                        elif "k" in flags:
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   316
                            keywords = self.re_keywords
8843
eb7b247a98ea kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8829
diff changeset
   317
25775
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   318
                elif code == "text" or code == "binary":
25882
97a9f7602014 convert: when getting file from Perforce concatenate data at the end
Eugene Baranov <eug.baranov@gmail.com>
parents: 25805
diff changeset
   319
                    contents.append(data)
25775
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   320
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   321
                lasterror = None
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   322
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   323
            if not lasterror:
220d9ae6a9a8 convert: if getting a file from Perforce fails try to get it one more time
Eugene Baranov <eug.baranov@gmail.com>
parents: 25760
diff changeset
   324
                break
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   325
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   326
        if mode is None:
22296
650b5b6e75ed convert: use None value for missing files instead of overloading IOError
Mads Kiilerich <madski@unity3d.com>
parents: 22294
diff changeset
   327
            return None, None
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   328
25882
97a9f7602014 convert: when getting file from Perforce concatenate data at the end
Eugene Baranov <eug.baranov@gmail.com>
parents: 25805
diff changeset
   329
        contents = ''.join(contents)
97a9f7602014 convert: when getting file from Perforce concatenate data at the end
Eugene Baranov <eug.baranov@gmail.com>
parents: 25805
diff changeset
   330
8829
ce4b92f5cea7 convert: Make P4 conversion cope with keywords, binary files and symbolic links.
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents: 8225
diff changeset
   331
        if keywords:
ce4b92f5cea7 convert: Make P4 conversion cope with keywords, binary files and symbolic links.
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents: 8225
diff changeset
   332
            contents = keywords.sub("$\\1$", contents)
ce4b92f5cea7 convert: Make P4 conversion cope with keywords, binary files and symbolic links.
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents: 8225
diff changeset
   333
        if mode == "l" and contents.endswith("\n"):
ce4b92f5cea7 convert: Make P4 conversion cope with keywords, binary files and symbolic links.
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents: 8225
diff changeset
   334
            contents = contents[:-1]
ce4b92f5cea7 convert: Make P4 conversion cope with keywords, binary files and symbolic links.
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents: 8225
diff changeset
   335
11134
33010ff1fd6f convert: merge sources getmode() into getfile()
Patrick Mezard <pmezard@gmail.com>
parents: 10939
diff changeset
   336
        return contents, mode
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   337
22300
35ab037de989 convert: introduce --full for converting all files
Mads Kiilerich <madski@unity3d.com>
parents: 22296
diff changeset
   338
    def getchanges(self, rev, full):
35ab037de989 convert: introduce --full for converting all files
Mads Kiilerich <madski@unity3d.com>
parents: 22296
diff changeset
   339
        if full:
26779
aaa33ec3c951 grammar: use does instead of do where appropriate
timeless@mozdev.org
parents: 26587
diff changeset
   340
            raise error.Abort(_("convert from p4 does not support --full"))
25751
17a9da909186 convert: handle copies when converting from Perforce (issue4744)
Eugene Baranov <eug.baranov@gmail.com>
parents: 25748
diff changeset
   341
        return self.files[rev], self.copies[rev], set()
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   342
30603
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   343
    def _construct_commit(self, obj, parents=None):
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   344
        """
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   345
        Constructs a common.commit object from an unmarshalled
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   346
        `p4 describe` output
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   347
        """
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   348
        desc = self.recode(obj.get("desc", ""))
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   349
        date = (int(obj["time"]), 0)     # timezone not set
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   350
        if parents is None:
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   351
            parents = []
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   352
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   353
        return common.commit(author=self.recode(obj["user"]),
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 35176
diff changeset
   354
            date=dateutil.datestr(date, '%Y-%m-%d %H:%M:%S %1%2'),
30603
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   355
            parents=parents, desc=desc, branch=None, rev=obj['change'],
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   356
            extra={"p4": obj['change'], "convert_revision": obj['change']})
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   357
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   358
    def _fetch_revision(self, rev):
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   359
        """Return an output of `p4 describe` including author, commit date as
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   360
        a dictionary."""
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   361
        cmd = "p4 -G describe -s %s" % rev
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37084
diff changeset
   362
        stdout = procutil.popen(cmd, mode='rb')
30603
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   363
        return marshal.load(stdout)
db9e883566e8 convert: encapsulate commit data fetching and commit object creation
David Soria Parra <davidsp@fb.com>
parents: 30602
diff changeset
   364
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   365
    def getcommit(self, rev):
30604
b654112a0119 convert: return commit objects for revisions in the revmap
David Soria Parra <davidsp@fb.com>
parents: 30603
diff changeset
   366
        if rev in self.changeset:
b654112a0119 convert: return commit objects for revisions in the revmap
David Soria Parra <davidsp@fb.com>
parents: 30603
diff changeset
   367
            return self.changeset[rev]
b654112a0119 convert: return commit objects for revisions in the revmap
David Soria Parra <davidsp@fb.com>
parents: 30603
diff changeset
   368
        elif rev in self.revmap:
b654112a0119 convert: return commit objects for revisions in the revmap
David Soria Parra <davidsp@fb.com>
parents: 30603
diff changeset
   369
            d = self._fetch_revision(rev)
b654112a0119 convert: return commit objects for revisions in the revmap
David Soria Parra <davidsp@fb.com>
parents: 30603
diff changeset
   370
            return self._construct_commit(d, parents=None)
b654112a0119 convert: return commit objects for revisions in the revmap
David Soria Parra <davidsp@fb.com>
parents: 30603
diff changeset
   371
        raise error.Abort(
b654112a0119 convert: return commit objects for revisions in the revmap
David Soria Parra <davidsp@fb.com>
parents: 30603
diff changeset
   372
            _("cannot find %s in the revmap or parsed changesets") % rev)
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   373
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   374
    def gettags(self):
30599
902c89df94e3 convert: remove unused dictionaries
David Soria Parra <davidsp@fb.com>
parents: 30598
diff changeset
   375
        return {}
7823
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   376
11efa41037e2 convert: Perforce source for conversion to Mercurial
Frank Kingswood <frank@kingswood-consulting.co.uk>
parents:
diff changeset
   377
    def getchangedfiles(self, rev, i):
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 8066
diff changeset
   378
        return sorted([x[0] for x in self.files[rev]])