##// END OF EJS Templates
filectx: add an overlayfilectx class...
Jun Wu -
r32239:07da778f default
parent child Browse files
Show More
@@ -687,7 +687,9 class basefilectx(object):
687 687 in the repo,
688 688 workingfilectx: a filecontext that represents files from the working
689 689 directory,
690 memfilectx: a filecontext that represents files in-memory."""
690 memfilectx: a filecontext that represents files in-memory,
691 overlayfilectx: duplicate another filecontext with some fields overridden.
692 """
691 693 @propertycache
692 694 def _filelog(self):
693 695 return self._repo.file(self._path)
@@ -2078,6 +2080,77 class memfilectx(committablefilectx):
2078 2080 """wraps repo.wwrite"""
2079 2081 self._data = data
2080 2082
2083 class overlayfilectx(committablefilectx):
2084 """Like memfilectx but take an original filectx and optional parameters to
2085 override parts of it. This is useful when fctx.data() is expensive (i.e.
2086 flag processor is expensive) and raw data, flags, and filenode could be
2087 reused (ex. rebase or mode-only amend a REVIDX_EXTSTORED file).
2088 """
2089
2090 def __init__(self, originalfctx, datafunc=None, path=None, flags=None,
2091 copied=None, ctx=None):
2092 """originalfctx: filecontext to duplicate
2093
2094 datafunc: None or a function to override data (file content). It is a
2095 function to be lazy. path, flags, copied, ctx: None or overridden value
2096
2097 copied could be (path, rev), or False. copied could also be just path,
2098 and will be converted to (path, nullid). This simplifies some callers.
2099 """
2100
2101 if path is None:
2102 path = originalfctx.path()
2103 if ctx is None:
2104 ctx = originalfctx.changectx()
2105 ctxmatch = lambda: True
2106 else:
2107 ctxmatch = lambda: ctx == originalfctx.changectx()
2108
2109 repo = originalfctx.repo()
2110 flog = originalfctx.filelog()
2111 super(overlayfilectx, self).__init__(repo, path, flog, ctx)
2112
2113 if copied is None:
2114 copied = originalfctx.renamed()
2115 copiedmatch = lambda: True
2116 else:
2117 if copied and not isinstance(copied, tuple):
2118 # repo._filecommit will recalculate copyrev so nullid is okay
2119 copied = (copied, nullid)
2120 copiedmatch = lambda: copied == originalfctx.renamed()
2121
2122 # When data, copied (could affect data), ctx (could affect filelog
2123 # parents) are not overridden, rawdata, rawflags, and filenode may be
2124 # reused (repo._filecommit should double check filelog parents).
2125 #
2126 # path, flags are not hashed in filelog (but in manifestlog) so they do
2127 # not affect reusable here.
2128 #
2129 # If ctx or copied is overridden to a same value with originalfctx,
2130 # still consider it's reusable. originalfctx.renamed() may be a bit
2131 # expensive so it's not called unless necessary. Assuming datafunc is
2132 # always expensive, do not call it for this "reusable" test.
2133 reusable = datafunc is None and ctxmatch() and copiedmatch()
2134
2135 if datafunc is None:
2136 datafunc = originalfctx.data
2137 if flags is None:
2138 flags = originalfctx.flags()
2139
2140 self._datafunc = datafunc
2141 self._flags = flags
2142 self._copied = copied
2143
2144 if reusable:
2145 # copy extra fields from originalfctx
2146 attrs = ['rawdata', 'rawflags', '_filenode', '_filerev']
2147 for attr in attrs:
2148 if util.safehasattr(originalfctx, attr):
2149 setattr(self, attr, getattr(originalfctx, attr))
2150
2151 def data(self):
2152 return self._datafunc()
2153
2081 2154 class metadataonlyctx(committablectx):
2082 2155 """Like memctx but it's reusing the manifest of different commit.
2083 2156 Intended to be used by lightweight operations that are creating
General Comments 0
You need to be logged in to leave comments. Login now