##// END OF EJS Templates
phases: fix performance regression with Python 2...
phases: fix performance regression with Python 2 Unlike Python 3, xrange doesn't support efficient "in" and uses a linear time scan instead. Expand the condition to handle it fast. Differential Revision: https://phab.mercurial-scm.org/D9072

File last commit:

r44187:c190f271 default
r46124:497271da default
Show More
p4.py
405 lines | 12.8 KiB | text/x-python | PythonLexer
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 # Perforce source for convert extension.
#
# Copyright 2009, Frank Kingswood <frank@kingswood-consulting.co.uk>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
timeless
convert: p4 use absolute_import
r28371 from __future__ import absolute_import
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
timeless
convert: p4 use absolute_import
r28371 import marshal
import re
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205 from mercurial.i18n import _
timeless
convert: p4 use absolute_import
r28371 from mercurial import (
error,
util,
)
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 from mercurial.utils import (
dateutil,
Yuya Nishihara
procutil: bulk-replace function calls to point to new module
r37138 procutil,
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 stringutil,
)
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
timeless
convert: p4 use absolute_import
r28371 from . import common
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
Augie Fackler
formatting: blacken the codebase...
r43346
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 def loaditer(f):
Matt Harbison
cleanup: fix docstring formatting...
r44226 """Yield the dictionary objects generated by p4"""
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 try:
while True:
d = marshal.load(f)
if not d:
break
yield d
except EOFError:
pass
Augie Fackler
formatting: blacken the codebase...
r43346
Eugene Baranov
convert: unescape Perforce-escaped special characters in filenames
r25788 def decodefilename(filename):
"""Perforce escapes special characters @, #, *, or %
with %40, %23, %2A, or %25 respectively
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> decodefilename(b'portable-net45%252Bnetcore45%252Bwp8%252BMonoAndroid')
Eugene Baranov
convert: unescape Perforce-escaped special characters in filenames
r25788 'portable-net45%2Bnetcore45%2Bwp8%2BMonoAndroid'
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> decodefilename(b'//Depot/Directory/%2525/%2523/%23%40.%2A')
Eugene Baranov
convert: unescape Perforce-escaped special characters in filenames
r25788 '//Depot/Directory/%25/%23/#@.*'
"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 replacements = [
(b'%2A', b'*'),
(b'%23', b'#'),
(b'%40', b'@'),
(b'%25', b'%'),
]
Eugene Baranov
convert: unescape Perforce-escaped special characters in filenames
r25788 for k, v in replacements:
filename = filename.replace(k, v)
return filename
Augie Fackler
formatting: blacken the codebase...
r43346
timeless
convert: p4 use absolute_import
r28371 class p4_source(common.converter_source):
Matt Harbison
convert: save an indicator of the repo type for sources and sinks...
r35168 def __init__(self, ui, repotype, path, revs=None):
Matt Harbison
convert: avoid wrong lfconvert defaults by moving configitems to core...
r35141 # avoid import cycle
from . import convcmd
Matt Harbison
convert: save an indicator of the repo type for sources and sinks...
r35168 super(p4_source, self).__init__(ui, repotype, path, revs=revs)
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b"/" in path and not path.startswith(b'//'):
Augie Fackler
formatting: blacken the codebase...
r43346 raise common.NoRepo(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'%s does not look like a P4 repository') % path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Mackall
convert: attempt to check repo type before checking for tool
r7973
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 common.checktool(b'p4', abort=False)
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
David Soria Parra
convert: allow passing in a revmap...
r30601 self.revmap = {}
Augie Fackler
formatting: blacken the codebase...
r43346 self.encoding = self.ui.config(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'convert', b'p4.encoding', convcmd.orig_encoding
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Mackall
many, many trivial check-code fixups
r10282 self.re_type = re.compile(
Gregory Szorc
convert: use raw string for regular expressions...
r41678 br"([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)"
Augie Fackler
formatting: blacken the codebase...
r43346 br"(\+\w+)?$"
)
Matt Mackall
many, many trivial check-code fixups
r10282 self.re_keywords = re.compile(
Gregory Szorc
convert: use raw string for regular expressions...
r41678 br"\$(Id|Header|Date|DateTime|Change|File|Revision|Author)"
Augie Fackler
formatting: blacken the codebase...
r43346 br":[^$\n]*\$"
)
Gregory Szorc
convert: use raw string for regular expressions...
r41678 self.re_keywords_old = re.compile(br"\$(Id|Header):[^$\n]*\$")
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
Durham Goode
convert: add support for specifying multiple revs...
r25748 if revs and len(revs) > 1:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(
b"p4 source does not support specifying "
b"multiple revisions"
)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
David Soria Parra
convert: allow passing in a revmap...
r30601 def setrevmap(self, revmap):
"""Sets the parsed revmap dictionary.
Revmap stores mappings from a source revision to a target revision.
It is set in convertcmd.convert and provided by the user as a file
on the commandline.
Revisions in the map are considered beeing present in the
repository and ignored during _parse(). This allows for incremental
imports if a revmap is provided.
"""
self.revmap = revmap
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 def _parse_view(self, path):
Matt Harbison
cleanup: fix docstring formatting...
r44226 """Read changes affecting the path"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd = b'p4 -G changes -s submitted %s' % procutil.shellquote(path)
stdout = procutil.popen(cmd, mode=b'rb')
David Soria Parra
convert: use return value in parse_view() instead of manipulating state
r30629 p4changes = {}
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 for d in loaditer(stdout):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 c = d.get(b"change", None)
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 if c:
David Soria Parra
convert: use return value in parse_view() instead of manipulating state
r30629 p4changes[c] = True
return p4changes
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
def _parse(self, ui, path):
Matt Harbison
cleanup: fix docstring formatting...
r44226 """Prepare list of P4 filenames and revisions to import"""
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 p4changes = {}
changeset = {}
files_map = {}
copies_map = {}
localname = {}
depotname = {}
heads = []
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'reading p4 views\n'))
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
# read client spec or view
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b"/" in path:
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 p4changes.update(self._parse_view(path))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if path.startswith(b"//") and path.endswith(b"/..."):
views = {path[:-3]: b""}
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 views = {b"//": b""}
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd = b'p4 -G client -o %s' % procutil.shellquote(path)
clientspec = marshal.load(procutil.popen(cmd, mode=b'rb'))
Dirkjan Ochtman
cleanup: remove all trailing whitespace
r7869
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 views = {}
for client in clientspec:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if client.startswith(b"View"):
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 sview, cview = clientspec[client].split()
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 p4changes.update(self._parse_view(sview))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if sview.endswith(b"...") and cview.endswith(b"..."):
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 sview = sview[:-3]
cview = cview[:-3]
cview = cview[2:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cview = cview[cview.find(b"/") + 1 :]
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 views[sview] = cview
# list of changes that affect our source files
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 p4changes = p4changes.keys()
p4changes.sort(key=int)
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
# list with depot pathnames, longest first
vieworder = views.keys()
Martin Geisler
p4: simplify sort key
r9039 vieworder.sort(key=len, reverse=True)
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
# handle revision limiting
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 startrev = self.ui.config(b'convert', b'p4.startrev')
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
# now read the full changelists to get the list of file revisions
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'collecting p4 changelists\n'))
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 lastid = None
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 for change in p4changes:
David Soria Parra
convert: don't use long list comprehensions...
r30597 if startrev and int(change) < int(startrev):
continue
if self.revs and int(change) > int(self.revs[0]):
continue
David Soria Parra
convert: allow passing in a revmap...
r30601 if change in self.revmap:
# Ignore already present revisions, but set the parent pointer.
lastid = change
continue
David Soria Parra
convert: don't use long list comprehensions...
r30597
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 if lastid:
parents = [lastid]
else:
parents = []
Dirkjan Ochtman
cleanup: remove all trailing whitespace
r7869
David Soria Parra
convert: encapsulate commit data fetching and commit object creation...
r30603 d = self._fetch_revision(change)
c = self._construct_commit(d, parents)
David Soria Parra
convert: fix the handling of empty changlist descriptions in P4...
r31590 descarr = c.desc.splitlines(True)
if len(descarr) > 0:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 shortdesc = descarr[0].rstrip(b'\r\n')
David Soria Parra
convert: fix the handling of empty changlist descriptions in P4...
r31590 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 shortdesc = b'**empty changelist description**'
David Soria Parra
convert: fix the handling of empty changlist descriptions in P4...
r31590
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 t = b'%s %s' % (c.rev, repr(shortdesc)[1:-1])
ui.status(stringutil.ellipsis(t, 80) + b'\n')
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
files = []
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751 copies = {}
copiedfiles = []
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 i = 0
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 while (b"depotFile%d" % i) in d and (b"rev%d" % i) in d:
oldname = d[b"depotFile%d" % i]
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 filename = None
for v in vieworder:
Eugene Baranov
convert: ignore case changes in vieworder for Perforce...
r25776 if oldname.lower().startswith(v.lower()):
Augie Fackler
formatting: blacken the codebase...
r43346 filename = decodefilename(views[v] + oldname[len(v) :])
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 break
if filename:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 files.append((filename, d[b"rev%d" % i]))
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 depotname[filename] = oldname
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if d.get(b"action%d" % i) == b"move/add":
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751 copiedfiles.append(filename)
David Soria Parra
convert: move localname state to function scope
r30630 localname[oldname] = filename
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 i += 1
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751
# Collect information about copied files
for filename in copiedfiles:
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 oldname = depotname[filename]
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 flcmd = b'p4 -G filelog %s' % procutil.shellquote(oldname)
flstdout = procutil.popen(flcmd, mode=b'rb')
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751
copiedfilename = None
for d in loaditer(flstdout):
copiedoldname = None
i = 0
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 while (b"change%d" % i) in d:
Augie Fackler
formatting: blacken the codebase...
r43346 if (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 d[b"change%d" % i] == change
and d[b"action%d" % i] == b"move/add"
Augie Fackler
formatting: blacken the codebase...
r43346 ):
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751 j = 0
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 while (b"file%d,%d" % (i, j)) in d:
if d[b"how%d,%d" % (i, j)] == b"moved from":
copiedoldname = d[b"file%d,%d" % (i, j)]
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751 break
j += 1
i += 1
David Soria Parra
convert: move localname state to function scope
r30630 if copiedoldname and copiedoldname in localname:
copiedfilename = localname[copiedoldname]
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751 break
if copiedfilename:
copies[filename] = copiedfilename
else:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"cannot find source for copied file: %s@%s\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % (filename, change)
)
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 changeset[change] = c
files_map[change] = files
copies_map[change] = copies
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 lastid = change
Dirkjan Ochtman
cleanup: remove all trailing whitespace
r7869
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 if lastid and len(changeset) > 0:
heads = [lastid]
return {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'changeset': changeset,
b'files': files_map,
b'copies': copies_map,
b'heads': heads,
b'depotname': depotname,
David Soria Parra
convert: return calculated values from parse() instead of manpulating state
r30631 }
David Soria Parra
convert: parse perforce data on-demand...
r30632 @util.propertycache
def _parse_once(self):
return self._parse(self.ui, self.path)
@util.propertycache
def copies(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._parse_once[b'copies']
David Soria Parra
convert: parse perforce data on-demand...
r30632
@util.propertycache
def files(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._parse_once[b'files']
David Soria Parra
convert: parse perforce data on-demand...
r30632
@util.propertycache
def changeset(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._parse_once[b'changeset']
David Soria Parra
convert: parse perforce data on-demand...
r30632
@util.propertycache
def heads(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._parse_once[b'heads']
David Soria Parra
convert: parse perforce data on-demand...
r30632
@util.propertycache
def depotname(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return self._parse_once[b'depotname']
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
def getheads(self):
return self.heads
def getfile(self, name, rev):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd = b'p4 -G print %s' % procutil.shellquote(
b"%s#%s" % (self.depotname[name], rev)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775 lasterror = None
while True:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 stdout = procutil.popen(cmd, mode=b'rb')
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775
mode = None
Eugene Baranov
convert: when getting file from Perforce concatenate data at the end...
r25882 contents = []
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775 keywords = None
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775 for d in loaditer(stdout):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 code = d[b"code"]
data = d.get(b"data")
Frank Kingswood
convert: Make P4 conversion cope with keywords, binary files and symbolic links....
r8829
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if code == b"error":
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775 # if this is the first time error happened
# re-attempt getting the file
if not lasterror:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 lasterror = IOError(d[b"generic"], data)
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775 # this will exit inner-most for-loop
break
else:
raise lasterror
Dirkjan Ochtman
kill trailing whitespace
r8843
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif code == b"stat":
action = d.get(b"action")
if action in [b"purge", b"delete", b"move/delete"]:
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775 return None, None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 p4type = self.re_type.match(d[b"type"])
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775 if p4type:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 mode = b""
flags = (p4type.group(1) or b"") + (
p4type.group(3) or b""
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b"x" in flags:
mode = b"x"
if p4type.group(2) == b"symlink":
mode = b"l"
if b"ko" in flags:
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775 keywords = self.re_keywords_old
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif b"k" in flags:
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775 keywords = self.re_keywords
Dirkjan Ochtman
kill trailing whitespace
r8843
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif code == b"text" or code == b"binary":
Eugene Baranov
convert: when getting file from Perforce concatenate data at the end...
r25882 contents.append(data)
Eugene Baranov
convert: if getting a file from Perforce fails try to get it one more time...
r25775
lasterror = None
if not lasterror:
break
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
if mode is None:
Mads Kiilerich
convert: use None value for missing files instead of overloading IOError...
r22296 return None, None
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 contents = b''.join(contents)
Eugene Baranov
convert: when getting file from Perforce concatenate data at the end...
r25882
Frank Kingswood
convert: Make P4 conversion cope with keywords, binary files and symbolic links....
r8829 if keywords:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 contents = keywords.sub(b"$\\1$", contents)
if mode == b"l" and contents.endswith(b"\n"):
Frank Kingswood
convert: Make P4 conversion cope with keywords, binary files and symbolic links....
r8829 contents = contents[:-1]
Patrick Mezard
convert: merge sources getmode() into getfile()
r11134 return contents, mode
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 def getchanges(self, rev, full):
if full:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"convert from p4 does not support --full"))
Eugene Baranov
convert: handle copies when converting from Perforce (issue4744)
r25751 return self.files[rev], self.copies[rev], set()
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
David Soria Parra
convert: encapsulate commit data fetching and commit object creation...
r30603 def _construct_commit(self, obj, parents=None):
"""
Constructs a common.commit object from an unmarshalled
`p4 describe` output
"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 desc = self.recode(obj.get(b"desc", b""))
date = (int(obj[b"time"]), 0) # timezone not set
David Soria Parra
convert: encapsulate commit data fetching and commit object creation...
r30603 if parents is None:
parents = []
Augie Fackler
formatting: blacken the codebase...
r43346 return common.commit(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 author=self.recode(obj[b"user"]),
date=dateutil.datestr(date, b'%Y-%m-%d %H:%M:%S %1%2'),
Augie Fackler
formatting: blacken the codebase...
r43346 parents=parents,
desc=desc,
branch=None,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rev=obj[b'change'],
extra={b"p4": obj[b'change'], b"convert_revision": obj[b'change']},
Augie Fackler
formatting: blacken the codebase...
r43346 )
David Soria Parra
convert: encapsulate commit data fetching and commit object creation...
r30603
def _fetch_revision(self, rev):
"""Return an output of `p4 describe` including author, commit date as
a dictionary."""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cmd = b"p4 -G describe -s %s" % rev
stdout = procutil.popen(cmd, mode=b'rb')
David Soria Parra
convert: encapsulate commit data fetching and commit object creation...
r30603 return marshal.load(stdout)
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823 def getcommit(self, rev):
David Soria Parra
convert: return commit objects for revisions in the revmap...
r30604 if rev in self.changeset:
return self.changeset[rev]
elif rev in self.revmap:
d = self._fetch_revision(rev)
return self._construct_commit(d, parents=None)
raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"cannot find %s in the revmap or parsed changesets") % rev
Augie Fackler
formatting: blacken the codebase...
r43346 )
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
def gettags(self):
David Soria Parra
convert: remove unused dictionaries...
r30599 return {}
Frank Kingswood
convert: Perforce source for conversion to Mercurial
r7823
def getchangedfiles(self, rev, i):
Matt Mackall
replace util.sort with sorted built-in...
r8209 return sorted([x[0] for x in self.files[rev]])