mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 00:14:35 +03:00
seqimport - make it survive CLs that have moves outside of clientspec
Summary: seqimport currently has a gap: if a changelist touches files outside of clientspec, it will blow up when trying to get the move info for it. Even if that was not the case, it could blow up if the file was moved into the clientspec. This change makes it resilient to that by providing the same list created by `parse_fstat` to prefilter files we check for move info, and then making `parse_where` take an optional parameter saying it is fine if file is not on client (i.e. moved into clientspec) Differential Revision: D7574415 fbshipit-source-id: 63f6a32436d3d53d6f9402575a9a13bb4187b76c
This commit is contained in:
parent
5346a46bb5
commit
1fde98d0db
@ -26,10 +26,14 @@ KEYWORD_REGEX = "\$(Id|Header|DateTime|" + \
|
||||
#TODO: make p4 user configurable
|
||||
P4_ADMIN_USER = 'p4admin'
|
||||
|
||||
def relpath(client, depotfile):
|
||||
def relpath(client, depotfile, ignore_nonexisting=False):
|
||||
where = p4.parse_where(client, depotfile)
|
||||
filename = where['clientFile'].replace('//%s/' % client, '')
|
||||
return p4.decodefilename(filename)
|
||||
filename = where.get('clientFile')
|
||||
if filename is not None:
|
||||
filename = filename.replace('//%s/' % client, '')
|
||||
elif not ignore_nonexisting:
|
||||
raise error.Abort('Could not find file %s' % (depotfile))
|
||||
return p4.decodefilename(filename) if filename is not None else filename
|
||||
|
||||
def get_localname(client, p4filelogs):
|
||||
for p4fl in p4filelogs:
|
||||
|
@ -47,7 +47,7 @@ class ChangelistImporter(object):
|
||||
else:
|
||||
added_or_modified.append((p4path, hgpath))
|
||||
|
||||
moved = self._get_move_info(p4cl)
|
||||
moved = self._get_move_info(p4cl, p4flogs)
|
||||
node = self._create_commit(p4cl, p4flogs, removed, moved)
|
||||
largefiles = self._get_largefiles(p4cl, added_or_modified, node)
|
||||
|
||||
@ -65,14 +65,30 @@ class ChangelistImporter(object):
|
||||
self.ui.debug('largefile: %s, oid: %s\n' % (hgpath, oid))
|
||||
return largefiles
|
||||
|
||||
def _get_move_info(self, p4cl):
|
||||
def _get_move_info(self, p4cl, p4flogs):
|
||||
'''Returns a dict where entries are (dst, src)'''
|
||||
moves = {}
|
||||
files_in_clientspec = {
|
||||
p4flog._depotfile: hgpath for hgpath, p4flog in p4flogs.items()
|
||||
}
|
||||
for filename, info in p4cl.parsed['files'].items():
|
||||
if filename not in files_in_clientspec:
|
||||
continue
|
||||
src = info.get('src')
|
||||
if src:
|
||||
hgsrc = importer.relpath(self.client, src)
|
||||
hgdst = importer.relpath(self.client, filename)
|
||||
hgdst = files_in_clientspec[filename]
|
||||
# The below could return None if the source of the move is
|
||||
# outside of client view. That is expected.
|
||||
# This info will be used when creating the commit, and value of
|
||||
# None in the moves dictionary is a no-op, it will treat it as
|
||||
# an add in hg. As it just came into the client view we cannot
|
||||
# store any move info for it in hg (even though it was a legit
|
||||
# move in perforce).
|
||||
hgsrc = importer.relpath(
|
||||
self.client,
|
||||
src,
|
||||
ignore_nonexisting=True,
|
||||
)
|
||||
moves[hgdst] = hgsrc
|
||||
return moves
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user