Patchwork [2,of,3] convert: implements targetfilebelongstosource for filemap source

login
register
mail settings
Submitter Durham Goode
Date Aug. 15, 2015, 9:11 p.m.
Message ID <7f5f25699b524f730664.1439673077@dev2000.prn2.facebook.com>
Download mbox | patch
Permalink /patch/10215/
State Accepted
Delegated to: Augie Fackler
Headers show

Comments

Durham Goode - Aug. 15, 2015, 9:11 p.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1439671590 25200
#      Sat Aug 15 13:46:30 2015 -0700
# Branch stable
# Node ID 7f5f25699b524f730664993416601a1df3ba9b9f
# Parent  3d65200552e6af37d0f520b45239e7f0afdda7a0
convert: implements targetfilebelongstosource for filemap source

This is an implementation of the new targetfilebelongstosource() function for
the filemapper. It simply checks if the given file name is prefixed by any of
the rename destinations.

It is not a perfect implementation since it doesn't account for the filemap
specifying includes or excludes, but that makes the problem much harder, and
this implementation should suffice for most cases.

Patch

diff --git a/hgext/convert/filemap.py b/hgext/convert/filemap.py
--- a/hgext/convert/filemap.py
+++ b/hgext/convert/filemap.py
@@ -42,6 +42,7 @@  class filemapper(object):
         self.include = {}
         self.exclude = {}
         self.rename = {}
+        self.targetprefixes = None
         if path:
             if self.parse(path):
                 raise util.Abort(_('errors in filemap'))
@@ -100,6 +101,30 @@  class filemapper(object):
                 pass
         return '', name, ''
 
+    def istargetfile(self, filename):
+        """Return true if the given target filename is covered as a destination
+        of the filemap. This is useful for identifying what parts of the target
+        repo belong to the source repo and what parts don't."""
+        if self.targetprefixes is None:
+            self.targetprefixes = set()
+            for before, after in self.rename.iteritems():
+                self.targetprefixes.add(after)
+
+        # If "." is a target, then all target files are considered from the
+        # source.
+        if not self.targetprefixes or '.' in self.targetprefixes:
+            return True
+
+        filename = normalize(filename)
+        for pre, suf in rpairs(filename):
+            # This check is imperfect since it doesn't account for the
+            # include/exclude list, but it should work in filemaps that don't
+            # apply include/exclude to the same source directories they are
+            # renaming.
+            if pre in self.targetprefixes:
+                return True
+        return False
+
     def __call__(self, name):
         if self.include:
             inc = self.lookup(name, self.include)[0]
@@ -410,6 +435,9 @@  class filemap_source(converter_source):
 
         return files, ncopies, ncleanp2
 
+    def targetfilebelongstosource(self, targetfilename):
+        return self.filemapper.istargetfile(targetfilename)
+
     def getfile(self, name, rev):
         realname, realrev = rev
         return self.base.getfile(realname, realrev)