Show More
@@ -1272,89 +1272,6 b' class filectx(basefilectx):' | |||
|
1272 | 1272 | return [filectx(self._repo, self._path, fileid=x, |
|
1273 | 1273 | filelog=self._filelog) for x in c] |
|
1274 | 1274 | |
|
1275 | def _changesrange(fctx1, fctx2, linerange2, diffopts): | |
|
1276 | """Return `(diffinrange, linerange1)` where `diffinrange` is True | |
|
1277 | if diff from fctx2 to fctx1 has changes in linerange2 and | |
|
1278 | `linerange1` is the new line range for fctx1. | |
|
1279 | """ | |
|
1280 | blocks = mdiff.allblocks(fctx1.data(), fctx2.data(), diffopts) | |
|
1281 | filteredblocks, linerange1 = mdiff.blocksinrange(blocks, linerange2) | |
|
1282 | diffinrange = any(stype == '!' for _, stype in filteredblocks) | |
|
1283 | return diffinrange, linerange1 | |
|
1284 | ||
|
1285 | def blockancestors(fctx, fromline, toline, followfirst=False): | |
|
1286 | """Yield ancestors of `fctx` with respect to the block of lines within | |
|
1287 | `fromline`-`toline` range. | |
|
1288 | """ | |
|
1289 | diffopts = patch.diffopts(fctx._repo.ui) | |
|
1290 | introrev = fctx.introrev() | |
|
1291 | if fctx.rev() != introrev: | |
|
1292 | fctx = fctx.filectx(fctx.filenode(), changeid=introrev) | |
|
1293 | visit = {(fctx.linkrev(), fctx.filenode()): (fctx, (fromline, toline))} | |
|
1294 | while visit: | |
|
1295 | c, linerange2 = visit.pop(max(visit)) | |
|
1296 | pl = c.parents() | |
|
1297 | if followfirst: | |
|
1298 | pl = pl[:1] | |
|
1299 | if not pl: | |
|
1300 | # The block originates from the initial revision. | |
|
1301 | yield c, linerange2 | |
|
1302 | continue | |
|
1303 | inrange = False | |
|
1304 | for p in pl: | |
|
1305 | inrangep, linerange1 = _changesrange(p, c, linerange2, diffopts) | |
|
1306 | inrange = inrange or inrangep | |
|
1307 | if linerange1[0] == linerange1[1]: | |
|
1308 | # Parent's linerange is empty, meaning that the block got | |
|
1309 | # introduced in this revision; no need to go futher in this | |
|
1310 | # branch. | |
|
1311 | continue | |
|
1312 | # Set _descendantrev with 'c' (a known descendant) so that, when | |
|
1313 | # _adjustlinkrev is called for 'p', it receives this descendant | |
|
1314 | # (as srcrev) instead possibly topmost introrev. | |
|
1315 | p._descendantrev = c.rev() | |
|
1316 | visit[p.linkrev(), p.filenode()] = p, linerange1 | |
|
1317 | if inrange: | |
|
1318 | yield c, linerange2 | |
|
1319 | ||
|
1320 | def blockdescendants(fctx, fromline, toline): | |
|
1321 | """Yield descendants of `fctx` with respect to the block of lines within | |
|
1322 | `fromline`-`toline` range. | |
|
1323 | """ | |
|
1324 | # First possibly yield 'fctx' if it has changes in range with respect to | |
|
1325 | # its parents. | |
|
1326 | try: | |
|
1327 | c, linerange1 = next(blockancestors(fctx, fromline, toline)) | |
|
1328 | except StopIteration: | |
|
1329 | pass | |
|
1330 | else: | |
|
1331 | if c == fctx: | |
|
1332 | yield c, linerange1 | |
|
1333 | ||
|
1334 | diffopts = patch.diffopts(fctx._repo.ui) | |
|
1335 | fl = fctx.filelog() | |
|
1336 | seen = {fctx.filerev(): (fctx, (fromline, toline))} | |
|
1337 | for i in fl.descendants([fctx.filerev()]): | |
|
1338 | c = fctx.filectx(i) | |
|
1339 | inrange = False | |
|
1340 | for x in fl.parentrevs(i): | |
|
1341 | try: | |
|
1342 | p, linerange2 = seen[x] | |
|
1343 | except KeyError: | |
|
1344 | # nullrev or other branch | |
|
1345 | continue | |
|
1346 | inrangep, linerange1 = _changesrange(c, p, linerange2, diffopts) | |
|
1347 | inrange = inrange or inrangep | |
|
1348 | # If revision 'i' has been seen (it's a merge), we assume that its | |
|
1349 | # line range is the same independently of which parents was used | |
|
1350 | # to compute it. | |
|
1351 | assert i not in seen or seen[i][1] == linerange1, ( | |
|
1352 | 'computed line range for %s is not consistent between ' | |
|
1353 | 'ancestor branches' % c) | |
|
1354 | seen[i] = c, linerange1 | |
|
1355 | if inrange: | |
|
1356 | yield c, linerange1 | |
|
1357 | ||
|
1358 | 1275 | class committablectx(basectx): |
|
1359 | 1276 | """A committablectx object provides common functionality for a context that |
|
1360 | 1277 | wants the ability to commit, e.g. workingctx or memctx.""" |
@@ -11,7 +11,9 b' import heapq' | |||
|
11 | 11 | |
|
12 | 12 | from . import ( |
|
13 | 13 | error, |
|
14 | mdiff, | |
|
14 | 15 | node, |
|
16 | patch, | |
|
15 | 17 | smartset, |
|
16 | 18 | ) |
|
17 | 19 | |
@@ -140,6 +142,89 b' def reachableroots(repo, roots, heads, i' | |||
|
140 | 142 | revs.sort() |
|
141 | 143 | return revs |
|
142 | 144 | |
|
145 | def _changesrange(fctx1, fctx2, linerange2, diffopts): | |
|
146 | """Return `(diffinrange, linerange1)` where `diffinrange` is True | |
|
147 | if diff from fctx2 to fctx1 has changes in linerange2 and | |
|
148 | `linerange1` is the new line range for fctx1. | |
|
149 | """ | |
|
150 | blocks = mdiff.allblocks(fctx1.data(), fctx2.data(), diffopts) | |
|
151 | filteredblocks, linerange1 = mdiff.blocksinrange(blocks, linerange2) | |
|
152 | diffinrange = any(stype == '!' for _, stype in filteredblocks) | |
|
153 | return diffinrange, linerange1 | |
|
154 | ||
|
155 | def blockancestors(fctx, fromline, toline, followfirst=False): | |
|
156 | """Yield ancestors of `fctx` with respect to the block of lines within | |
|
157 | `fromline`-`toline` range. | |
|
158 | """ | |
|
159 | diffopts = patch.diffopts(fctx._repo.ui) | |
|
160 | introrev = fctx.introrev() | |
|
161 | if fctx.rev() != introrev: | |
|
162 | fctx = fctx.filectx(fctx.filenode(), changeid=introrev) | |
|
163 | visit = {(fctx.linkrev(), fctx.filenode()): (fctx, (fromline, toline))} | |
|
164 | while visit: | |
|
165 | c, linerange2 = visit.pop(max(visit)) | |
|
166 | pl = c.parents() | |
|
167 | if followfirst: | |
|
168 | pl = pl[:1] | |
|
169 | if not pl: | |
|
170 | # The block originates from the initial revision. | |
|
171 | yield c, linerange2 | |
|
172 | continue | |
|
173 | inrange = False | |
|
174 | for p in pl: | |
|
175 | inrangep, linerange1 = _changesrange(p, c, linerange2, diffopts) | |
|
176 | inrange = inrange or inrangep | |
|
177 | if linerange1[0] == linerange1[1]: | |
|
178 | # Parent's linerange is empty, meaning that the block got | |
|
179 | # introduced in this revision; no need to go futher in this | |
|
180 | # branch. | |
|
181 | continue | |
|
182 | # Set _descendantrev with 'c' (a known descendant) so that, when | |
|
183 | # _adjustlinkrev is called for 'p', it receives this descendant | |
|
184 | # (as srcrev) instead possibly topmost introrev. | |
|
185 | p._descendantrev = c.rev() | |
|
186 | visit[p.linkrev(), p.filenode()] = p, linerange1 | |
|
187 | if inrange: | |
|
188 | yield c, linerange2 | |
|
189 | ||
|
190 | def blockdescendants(fctx, fromline, toline): | |
|
191 | """Yield descendants of `fctx` with respect to the block of lines within | |
|
192 | `fromline`-`toline` range. | |
|
193 | """ | |
|
194 | # First possibly yield 'fctx' if it has changes in range with respect to | |
|
195 | # its parents. | |
|
196 | try: | |
|
197 | c, linerange1 = next(blockancestors(fctx, fromline, toline)) | |
|
198 | except StopIteration: | |
|
199 | pass | |
|
200 | else: | |
|
201 | if c == fctx: | |
|
202 | yield c, linerange1 | |
|
203 | ||
|
204 | diffopts = patch.diffopts(fctx._repo.ui) | |
|
205 | fl = fctx.filelog() | |
|
206 | seen = {fctx.filerev(): (fctx, (fromline, toline))} | |
|
207 | for i in fl.descendants([fctx.filerev()]): | |
|
208 | c = fctx.filectx(i) | |
|
209 | inrange = False | |
|
210 | for x in fl.parentrevs(i): | |
|
211 | try: | |
|
212 | p, linerange2 = seen[x] | |
|
213 | except KeyError: | |
|
214 | # nullrev or other branch | |
|
215 | continue | |
|
216 | inrangep, linerange1 = _changesrange(c, p, linerange2, diffopts) | |
|
217 | inrange = inrange or inrangep | |
|
218 | # If revision 'i' has been seen (it's a merge), we assume that its | |
|
219 | # line range is the same independently of which parents was used | |
|
220 | # to compute it. | |
|
221 | assert i not in seen or seen[i][1] == linerange1, ( | |
|
222 | 'computed line range for %s is not consistent between ' | |
|
223 | 'ancestor branches' % c) | |
|
224 | seen[i] = c, linerange1 | |
|
225 | if inrange: | |
|
226 | yield c, linerange1 | |
|
227 | ||
|
143 | 228 | def toposort(revs, parentsfunc, firstbranch=()): |
|
144 | 229 | """Yield revisions from heads to roots one (topo) branch at a time. |
|
145 | 230 |
@@ -28,7 +28,7 b' from .common import (' | |||
|
28 | 28 | |
|
29 | 29 | from .. import ( |
|
30 | 30 | archival, |
|
31 | context, | |
|
31 | dagop, | |
|
32 | 32 | encoding, |
|
33 | 33 | error, |
|
34 | 34 | graphmod, |
@@ -1013,9 +1013,9 b' def filelog(web, req, tmpl):' | |||
|
1013 | 1013 | # would required a dedicated "revnav" class |
|
1014 | 1014 | nav = None |
|
1015 | 1015 | if descend: |
|
1016 |
it = |
|
|
1016 | it = dagop.blockdescendants(fctx, *lrange) | |
|
1017 | 1017 | else: |
|
1018 |
it = |
|
|
1018 | it = dagop.blockancestors(fctx, *lrange) | |
|
1019 | 1019 | for i, (c, lr) in enumerate(it, 1): |
|
1020 | 1020 | diffs = None |
|
1021 | 1021 | if patch: |
@@ -827,8 +827,6 b' def followlines(repo, subset, x):' | |||
|
827 | 827 | descendants of 'startrev' are returned though renames are (currently) not |
|
828 | 828 | followed in this direction. |
|
829 | 829 | """ |
|
830 | from . import context # avoid circular import issues | |
|
831 | ||
|
832 | 830 | args = getargsdict(x, 'followlines', 'file *lines startrev descend') |
|
833 | 831 | if len(args['lines']) != 1: |
|
834 | 832 | raise error.ParseError(_("followlines requires a line range")) |
@@ -868,12 +866,12 b' def followlines(repo, subset, x):' | |||
|
868 | 866 | if descend: |
|
869 | 867 | rs = generatorset( |
|
870 | 868 | (c.rev() for c, _linerange |
|
871 |
in |
|
|
869 | in dagop.blockdescendants(fctx, fromline, toline)), | |
|
872 | 870 | iterasc=True) |
|
873 | 871 | else: |
|
874 | 872 | rs = generatorset( |
|
875 | 873 | (c.rev() for c, _linerange |
|
876 |
in |
|
|
874 | in dagop.blockancestors(fctx, fromline, toline)), | |
|
877 | 875 | iterasc=False) |
|
878 | 876 | return subset & rs |
|
879 | 877 |
General Comments 0
You need to be logged in to leave comments.
Login now