##// END OF EJS Templates
filelog: stop proxying datafile (API)...
Gregory Szorc -
r39818:03bedf1d default
parent child Browse files
Show More
@@ -1,266 +1,262 b''
1 1 # filelog.py - file history class for mercurial
2 2 #
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
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 . import (
11 11 error,
12 12 repository,
13 13 revlog,
14 14 )
15 15 from .utils import (
16 16 interfaceutil,
17 17 )
18 18
19 19 @interfaceutil.implementer(repository.ifilestorage)
20 20 class filelog(object):
21 21 def __init__(self, opener, path):
22 22 self._revlog = revlog.revlog(opener,
23 23 '/'.join(('data', path + '.i')),
24 24 censorable=True)
25 25 # full name of the user visible file, relative to the repository root
26 26 self.filename = path
27 27 self.index = self._revlog.index
28 28 self.version = self._revlog.version
29 29 self._generaldelta = self._revlog._generaldelta
30 30
31 31 def __len__(self):
32 32 return len(self._revlog)
33 33
34 34 def __iter__(self):
35 35 return self._revlog.__iter__()
36 36
37 37 def revs(self, start=0, stop=None):
38 38 return self._revlog.revs(start=start, stop=stop)
39 39
40 40 def parents(self, node):
41 41 return self._revlog.parents(node)
42 42
43 43 def parentrevs(self, rev):
44 44 return self._revlog.parentrevs(rev)
45 45
46 46 def rev(self, node):
47 47 return self._revlog.rev(node)
48 48
49 49 def node(self, rev):
50 50 return self._revlog.node(rev)
51 51
52 52 def lookup(self, node):
53 53 return self._revlog.lookup(node)
54 54
55 55 def linkrev(self, rev):
56 56 return self._revlog.linkrev(rev)
57 57
58 58 def flags(self, rev):
59 59 return self._revlog.flags(rev)
60 60
61 61 def commonancestorsheads(self, node1, node2):
62 62 return self._revlog.commonancestorsheads(node1, node2)
63 63
64 64 def descendants(self, revs):
65 65 return self._revlog.descendants(revs)
66 66
67 67 def headrevs(self):
68 68 return self._revlog.headrevs()
69 69
70 70 def heads(self, start=None, stop=None):
71 71 return self._revlog.heads(start, stop)
72 72
73 73 def children(self, node):
74 74 return self._revlog.children(node)
75 75
76 76 def deltaparent(self, rev):
77 77 return self._revlog.deltaparent(rev)
78 78
79 79 def iscensored(self, rev):
80 80 return self._revlog.iscensored(rev)
81 81
82 82 def rawsize(self, rev):
83 83 return self._revlog.rawsize(rev)
84 84
85 85 def checkhash(self, text, node, p1=None, p2=None, rev=None):
86 86 return self._revlog.checkhash(text, node, p1=p1, p2=p2, rev=rev)
87 87
88 88 def revision(self, node, _df=None, raw=False):
89 89 return self._revlog.revision(node, _df=_df, raw=raw)
90 90
91 91 def revdiff(self, rev1, rev2):
92 92 return self._revlog.revdiff(rev1, rev2)
93 93
94 94 def emitrevisiondeltas(self, requests):
95 95 return self._revlog.emitrevisiondeltas(requests)
96 96
97 97 def addrevision(self, revisiondata, transaction, linkrev, p1, p2,
98 98 node=None, flags=revlog.REVIDX_DEFAULT_FLAGS,
99 99 cachedelta=None):
100 100 return self._revlog.addrevision(revisiondata, transaction, linkrev,
101 101 p1, p2, node=node, flags=flags,
102 102 cachedelta=cachedelta)
103 103
104 104 def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None):
105 105 return self._revlog.addgroup(deltas, linkmapper, transaction,
106 106 addrevisioncb=addrevisioncb)
107 107
108 108 def getstrippoint(self, minlink):
109 109 return self._revlog.getstrippoint(minlink)
110 110
111 111 def strip(self, minlink, transaction):
112 112 return self._revlog.strip(minlink, transaction)
113 113
114 114 def censorrevision(self, tr, node, tombstone=b''):
115 115 return self._revlog.censorrevision(node, tombstone=tombstone)
116 116
117 117 def files(self):
118 118 return self._revlog.files()
119 119
120 120 def checksize(self):
121 121 return self._revlog.checksize()
122 122
123 123 def read(self, node):
124 124 t = self.revision(node)
125 125 if not t.startswith('\1\n'):
126 126 return t
127 127 s = t.index('\1\n', 2)
128 128 return t[s + 2:]
129 129
130 130 def add(self, text, meta, transaction, link, p1=None, p2=None):
131 131 if meta or text.startswith('\1\n'):
132 132 text = revlog.packmeta(meta, text)
133 133 return self.addrevision(text, transaction, link, p1, p2)
134 134
135 135 def renamed(self, node):
136 136 if self.parents(node)[0] != revlog.nullid:
137 137 return False
138 138 t = self.revision(node)
139 139 m = revlog.parsemeta(t)[0]
140 140 # copy and copyrev occur in pairs. In rare cases due to bugs,
141 141 # one can occur without the other.
142 142 if m and "copy" in m and "copyrev" in m:
143 143 return (m["copy"], revlog.bin(m["copyrev"]))
144 144 return False
145 145
146 146 def size(self, rev):
147 147 """return the size of a given revision"""
148 148
149 149 # for revisions with renames, we have to go the slow way
150 150 node = self.node(rev)
151 151 if self.renamed(node):
152 152 return len(self.read(node))
153 153 if self.iscensored(rev):
154 154 return 0
155 155
156 156 # XXX if self.read(node).startswith("\1\n"), this returns (size+4)
157 157 return self._revlog.size(rev)
158 158
159 159 def cmp(self, node, text):
160 160 """compare text with a given file revision
161 161
162 162 returns True if text is different than what is stored.
163 163 """
164 164
165 165 t = text
166 166 if text.startswith('\1\n'):
167 167 t = '\1\n\1\n' + text
168 168
169 169 samehashes = not self._revlog.cmp(node, t)
170 170 if samehashes:
171 171 return False
172 172
173 173 # censored files compare against the empty file
174 174 if self.iscensored(self.rev(node)):
175 175 return text != ''
176 176
177 177 # renaming a file produces a different hash, even if the data
178 178 # remains unchanged. Check if it's the case (slow):
179 179 if self.renamed(node):
180 180 t2 = self.read(node)
181 181 return t2 != text
182 182
183 183 return True
184 184
185 185 @property
186 186 def filename(self):
187 187 return self._revlog.filename
188 188
189 189 @filename.setter
190 190 def filename(self, value):
191 191 self._revlog.filename = value
192 192
193 193 # TODO these aren't part of the interface and aren't internal methods.
194 194 # Callers should be fixed to not use them.
195 195 @property
196 196 def indexfile(self):
197 197 return self._revlog.indexfile
198 198
199 199 @indexfile.setter
200 200 def indexfile(self, value):
201 201 self._revlog.indexfile = value
202 202
203 203 @property
204 def datafile(self):
205 return self._revlog.datafile
206
207 @property
208 204 def opener(self):
209 205 return self._revlog.opener
210 206
211 207 def clone(self, tr, destrevlog, **kwargs):
212 208 if not isinstance(destrevlog, filelog):
213 209 raise error.ProgrammingError('expected filelog to clone()')
214 210
215 211 return self._revlog.clone(tr, destrevlog._revlog, **kwargs)
216 212
217 213 class narrowfilelog(filelog):
218 214 """Filelog variation to be used with narrow stores."""
219 215
220 216 def __init__(self, opener, path, narrowmatch):
221 217 super(narrowfilelog, self).__init__(opener, path)
222 218 self._narrowmatch = narrowmatch
223 219
224 220 def renamed(self, node):
225 221 res = super(narrowfilelog, self).renamed(node)
226 222
227 223 # Renames that come from outside the narrowspec are problematic
228 224 # because we may lack the base text for the rename. This can result
229 225 # in code attempting to walk the ancestry or compute a diff
230 226 # encountering a missing revision. We address this by silently
231 227 # removing rename metadata if the source file is outside the
232 228 # narrow spec.
233 229 #
234 230 # A better solution would be to see if the base revision is available,
235 231 # rather than assuming it isn't.
236 232 #
237 233 # An even better solution would be to teach all consumers of rename
238 234 # metadata that the base revision may not be available.
239 235 #
240 236 # TODO consider better ways of doing this.
241 237 if res and not self._narrowmatch(res[0]):
242 238 return None
243 239
244 240 return res
245 241
246 242 def size(self, rev):
247 243 # Because we have a custom renamed() that may lie, we need to call
248 244 # the base renamed() to report accurate results.
249 245 node = self.node(rev)
250 246 if super(narrowfilelog, self).renamed(node):
251 247 return len(self.read(node))
252 248 else:
253 249 return super(narrowfilelog, self).size(rev)
254 250
255 251 def cmp(self, node, text):
256 252 different = super(narrowfilelog, self).cmp(node, text)
257 253
258 254 # Because renamed() may lie, we may get false positives for
259 255 # different content. Check for this by comparing against the original
260 256 # renamed() implementation.
261 257 if different:
262 258 if super(narrowfilelog, self).renamed(node):
263 259 t2 = self.read(node)
264 260 return t2 != text
265 261
266 262 return different
General Comments 0
You need to be logged in to leave comments. Login now