##// END OF EJS Templates
narrow: assume addflagprocessor will always exist on revlog module...
Augie Fackler -
r36100:9772ef9f default
parent child Browse files
Show More
@@ -1,162 +1,161 b''
1 1 # narrowrevlog.py - revlog storing irrelevant nodes as "ellipsis" nodes
2 2 #
3 3 # Copyright 2017 Google, Inc.
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 from mercurial import (
11 11 manifest,
12 12 revlog,
13 13 util,
14 14 )
15 15
16 16 ELLIPSIS_NODE_FLAG = 1 << 14
17 17 revlog.REVIDX_KNOWN_FLAGS |= ELLIPSIS_NODE_FLAG
18 18 if ELLIPSIS_NODE_FLAG not in revlog.REVIDX_FLAGS_ORDER:
19 19 revlog.REVIDX_FLAGS_ORDER.append(ELLIPSIS_NODE_FLAG)
20 20
21 21 def readtransform(self, text):
22 22 return text, False
23 23
24 24 def writetransform(self, text):
25 25 return text, False
26 26
27 27 def rawtransform(self, text):
28 28 return False
29 29
30 if util.safehasattr(revlog, 'addflagprocessor'):
31 revlog.addflagprocessor(ELLIPSIS_NODE_FLAG,
32 (readtransform, writetransform, rawtransform))
30 revlog.addflagprocessor(ELLIPSIS_NODE_FLAG,
31 (readtransform, writetransform, rawtransform))
33 32
34 33 def setup():
35 34 # We just wanted to add the flag processor, which is done at module
36 35 # load time.
37 36 pass
38 37
39 38 class excludeddir(manifest.treemanifest):
40 39 def __init__(self, dir, node):
41 40 super(excludeddir, self).__init__(dir)
42 41 self._node = node
43 42 # Add an empty file, which will be included by iterators and such,
44 43 # appearing as the directory itself (i.e. something like "dir/")
45 44 self._files[''] = node
46 45 self._flags[''] = 't'
47 46
48 47 # Manifests outside the narrowspec should never be modified, so avoid
49 48 # copying. This makes a noticeable difference when there are very many
50 49 # directories outside the narrowspec. Also, it makes sense for the copy to
51 50 # be of the same type as the original, which would not happen with the
52 51 # super type's copy().
53 52 def copy(self):
54 53 return self
55 54
56 55 class excludeddirmanifestctx(manifest.treemanifestctx):
57 56 def __init__(self, dir, node):
58 57 self._dir = dir
59 58 self._node = node
60 59
61 60 def read(self):
62 61 return excludeddir(self._dir, self._node)
63 62
64 63 def write(self, *args):
65 64 raise AssertionError('Attempt to write manifest from excluded dir %s' %
66 65 self._dir)
67 66
68 67 class excludedmanifestrevlog(manifest.manifestrevlog):
69 68 def __init__(self, dir):
70 69 self._dir = dir
71 70
72 71 def __len__(self):
73 72 raise AssertionError('Attempt to get length of excluded dir %s' %
74 73 self._dir)
75 74
76 75 def rev(self, node):
77 76 raise AssertionError('Attempt to get rev from excluded dir %s' %
78 77 self._dir)
79 78
80 79 def linkrev(self, node):
81 80 raise AssertionError('Attempt to get linkrev from excluded dir %s' %
82 81 self._dir)
83 82
84 83 def node(self, rev):
85 84 raise AssertionError('Attempt to get node from excluded dir %s' %
86 85 self._dir)
87 86
88 87 def add(self, *args, **kwargs):
89 88 # We should never write entries in dirlogs outside the narrow clone.
90 89 # However, the method still gets called from writesubtree() in
91 90 # _addtree(), so we need to handle it. We should possibly make that
92 91 # avoid calling add() with a clean manifest (_dirty is always False
93 92 # in excludeddir instances).
94 93 pass
95 94
96 95 def makenarrowmanifestrevlog(mfrevlog, repo):
97 96 if util.safehasattr(mfrevlog, '_narrowed'):
98 97 return
99 98
100 99 class narrowmanifestrevlog(mfrevlog.__class__):
101 100 # This function is called via debug{revlog,index,data}, but also during
102 101 # at least some push operations. This will be used to wrap/exclude the
103 102 # child directories when using treemanifests.
104 103 def dirlog(self, dir):
105 104 if dir and not dir.endswith('/'):
106 105 dir = dir + '/'
107 106 if not repo.narrowmatch().visitdir(dir[:-1] or '.'):
108 107 return excludedmanifestrevlog(dir)
109 108 result = super(narrowmanifestrevlog, self).dirlog(dir)
110 109 makenarrowmanifestrevlog(result, repo)
111 110 return result
112 111
113 112 mfrevlog.__class__ = narrowmanifestrevlog
114 113 mfrevlog._narrowed = True
115 114
116 115 def makenarrowmanifestlog(mfl, repo):
117 116 class narrowmanifestlog(mfl.__class__):
118 117 def get(self, dir, node, verify=True):
119 118 if not repo.narrowmatch().visitdir(dir[:-1] or '.'):
120 119 return excludeddirmanifestctx(dir, node)
121 120 return super(narrowmanifestlog, self).get(dir, node, verify=verify)
122 121 mfl.__class__ = narrowmanifestlog
123 122
124 123 def makenarrowfilelog(fl, narrowmatch):
125 124 class narrowfilelog(fl.__class__):
126 125 def renamed(self, node):
127 126 m = super(narrowfilelog, self).renamed(node)
128 127 if m and not narrowmatch(m[0]):
129 128 return None
130 129 return m
131 130
132 131 def size(self, rev):
133 132 # We take advantage of the fact that remotefilelog
134 133 # lacks a node() method to just skip the
135 134 # rename-checking logic when on remotefilelog. This
136 135 # might be incorrect on other non-revlog-based storage
137 136 # engines, but for now this seems to be fine.
138 137 if util.safehasattr(self, 'node'):
139 138 node = self.node(rev)
140 139 # Because renamed() is overridden above to
141 140 # sometimes return None even if there is metadata
142 141 # in the revlog, size can be incorrect for
143 142 # copies/renames, so we need to make sure we call
144 143 # the super class's implementation of renamed()
145 144 # for the purpose of size calculation.
146 145 if super(narrowfilelog, self).renamed(node):
147 146 return len(self.read(node))
148 147 return super(narrowfilelog, self).size(rev)
149 148
150 149 def cmp(self, node, text):
151 150 different = super(narrowfilelog, self).cmp(node, text)
152 151 if different:
153 152 # Similar to size() above, if the file was copied from
154 153 # a file outside the narrowspec, the super class's
155 154 # would have returned True because we tricked it into
156 155 # thinking that the file was not renamed.
157 156 if super(narrowfilelog, self).renamed(node):
158 157 t2 = self.read(node)
159 158 return t2 != text
160 159 return different
161 160
162 161 fl.__class__ = narrowfilelog
General Comments 0
You need to be logged in to leave comments. Login now