##// END OF EJS Templates
cmdutil: remove remainder of old walkchangerevs() implementation
Yuya Nishihara -
r46228:c7413ffe default
parent child Browse files
Show More
@@ -136,7 +136,6 b' from mercurial.pycompat import open'
136 136 from mercurial import (
137 137 changegroup,
138 138 changelog,
139 cmdutil,
140 139 commands,
141 140 configitems,
142 141 context,
@@ -341,7 +340,6 b' def uisetup(ui):'
341 340 extensions.wrapfunction(scmutil, b'getrenamedfn', getrenamedfn)
342 341 extensions.wrapfunction(revset, b'filelog', filelogrevset)
343 342 revset.symbols[b'filelog'] = revset.filelog
344 extensions.wrapfunction(cmdutil, b'walkfilerevs', walkfilerevs)
345 343
346 344
347 345 def cloneshallow(orig, ui, repo, *args, **opts):
@@ -782,40 +780,6 b' def getrenamedfn(orig, repo, endrev=None'
782 780 return getrenamed
783 781
784 782
785 def walkfilerevs(orig, repo, match, follow, revs, fncache):
786 if not isenabled(repo):
787 return orig(repo, match, follow, revs, fncache)
788
789 # remotefilelog's can't be walked in rev order, so throw.
790 # The caller will see the exception and walk the commit tree instead.
791 if not follow:
792 raise cmdutil.FileWalkError(b"Cannot walk via filelog")
793
794 wanted = set()
795 minrev, maxrev = min(revs), max(revs)
796
797 pctx = repo[b'.']
798 for filename in match.files():
799 if filename not in pctx:
800 raise error.Abort(
801 _(b'cannot follow file not in parent revision: "%s"') % filename
802 )
803 fctx = pctx[filename]
804
805 linkrev = fctx.linkrev()
806 if linkrev >= minrev and linkrev <= maxrev:
807 fncache.setdefault(linkrev, []).append(filename)
808 wanted.add(linkrev)
809
810 for ancestor in fctx.ancestors():
811 linkrev = ancestor.linkrev()
812 if linkrev >= minrev and linkrev <= maxrev:
813 fncache.setdefault(linkrev, []).append(ancestor.path())
814 wanted.add(linkrev)
815
816 return wanted
817
818
819 783 def filelogrevset(orig, repo, subset, x):
820 784 """``filelog(pattern)``
821 785 Changesets connected to the specified filelog.
@@ -16,7 +16,6 b' from .i18n import _'
16 16 from .node import (
17 17 hex,
18 18 nullid,
19 nullrev,
20 19 short,
21 20 )
22 21 from .pycompat import (
@@ -49,7 +48,6 b' from . import ('
49 48 revlog,
50 49 rewriteutil,
51 50 scmutil,
52 smartset,
53 51 state as statemod,
54 52 subrepoutil,
55 53 templatekw,
@@ -2249,185 +2247,6 b' def increasingwindows(windowsize=8, size'
2249 2247 windowsize *= 2
2250 2248
2251 2249
2252 def _walkrevs(repo, opts):
2253 # Default --rev value depends on --follow but --follow behavior
2254 # depends on revisions resolved from --rev...
2255 follow = opts.get(b'follow') or opts.get(b'follow_first')
2256 revspec = opts.get(b'rev')
2257 if follow and revspec:
2258 revs = scmutil.revrange(repo, revspec)
2259 revs = repo.revs(b'reverse(::%ld)', revs)
2260 elif revspec:
2261 revs = scmutil.revrange(repo, revspec)
2262 elif follow and repo.dirstate.p1() == nullid:
2263 revs = smartset.baseset()
2264 elif follow:
2265 revs = repo.revs(b'reverse(:.)')
2266 else:
2267 revs = smartset.spanset(repo)
2268 revs.reverse()
2269 return revs
2270
2271
2272 class FileWalkError(Exception):
2273 pass
2274
2275
2276 def walkfilerevs(repo, match, follow, revs, fncache):
2277 '''Walks the file history for the matched files.
2278
2279 Returns the changeset revs that are involved in the file history.
2280
2281 Throws FileWalkError if the file history can't be walked using
2282 filelogs alone.
2283 '''
2284 wanted = set()
2285 copies = []
2286 minrev, maxrev = min(revs), max(revs)
2287
2288 def filerevs(filelog, last):
2289 """
2290 Only files, no patterns. Check the history of each file.
2291
2292 Examines filelog entries within minrev, maxrev linkrev range
2293 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
2294 tuples in backwards order
2295 """
2296 cl_count = len(repo)
2297 revs = []
2298 for j in pycompat.xrange(0, last + 1):
2299 linkrev = filelog.linkrev(j)
2300 if linkrev < minrev:
2301 continue
2302 # only yield rev for which we have the changelog, it can
2303 # happen while doing "hg log" during a pull or commit
2304 if linkrev >= cl_count:
2305 break
2306
2307 parentlinkrevs = []
2308 for p in filelog.parentrevs(j):
2309 if p != nullrev:
2310 parentlinkrevs.append(filelog.linkrev(p))
2311 n = filelog.node(j)
2312 revs.append(
2313 (linkrev, parentlinkrevs, follow and filelog.renamed(n))
2314 )
2315
2316 return reversed(revs)
2317
2318 def iterfiles():
2319 pctx = repo[b'.']
2320 for filename in match.files():
2321 if follow:
2322 if filename not in pctx:
2323 raise error.Abort(
2324 _(
2325 b'cannot follow file not in parent '
2326 b'revision: "%s"'
2327 )
2328 % filename
2329 )
2330 yield filename, pctx[filename].filenode()
2331 else:
2332 yield filename, None
2333 for filename_node in copies:
2334 yield filename_node
2335
2336 for file_, node in iterfiles():
2337 filelog = repo.file(file_)
2338 if not len(filelog):
2339 if node is None:
2340 # A zero count may be a directory or deleted file, so
2341 # try to find matching entries on the slow path.
2342 if follow:
2343 raise error.Abort(
2344 _(b'cannot follow nonexistent file: "%s"') % file_
2345 )
2346 raise FileWalkError(b"Cannot walk via filelog")
2347 else:
2348 continue
2349
2350 if node is None:
2351 last = len(filelog) - 1
2352 else:
2353 last = filelog.rev(node)
2354
2355 # keep track of all ancestors of the file
2356 ancestors = {filelog.linkrev(last)}
2357
2358 # iterate from latest to oldest revision
2359 for rev, flparentlinkrevs, copied in filerevs(filelog, last):
2360 if not follow:
2361 if rev > maxrev:
2362 continue
2363 else:
2364 # Note that last might not be the first interesting
2365 # rev to us:
2366 # if the file has been changed after maxrev, we'll
2367 # have linkrev(last) > maxrev, and we still need
2368 # to explore the file graph
2369 if rev not in ancestors:
2370 continue
2371 # XXX insert 1327 fix here
2372 if flparentlinkrevs:
2373 ancestors.update(flparentlinkrevs)
2374
2375 fncache.setdefault(rev, []).append(file_)
2376 wanted.add(rev)
2377 if copied:
2378 copies.append(copied)
2379
2380 return wanted
2381
2382
2383 class _followfilter(object):
2384 def __init__(self, repo, onlyfirst=False):
2385 self.repo = repo
2386 self.startrev = nullrev
2387 self.roots = set()
2388 self.onlyfirst = onlyfirst
2389
2390 def match(self, rev):
2391 def realparents(rev):
2392 try:
2393 if self.onlyfirst:
2394 return self.repo.changelog.parentrevs(rev)[0:1]
2395 else:
2396 return filter(
2397 lambda x: x != nullrev,
2398 self.repo.changelog.parentrevs(rev),
2399 )
2400 except error.WdirUnsupported:
2401 prevs = [p.rev() for p in self.repo[rev].parents()]
2402 if self.onlyfirst:
2403 return prevs[:1]
2404 else:
2405 return prevs
2406
2407 if self.startrev == nullrev:
2408 self.startrev = rev
2409 return True
2410
2411 if rev > self.startrev:
2412 # forward: all descendants
2413 if not self.roots:
2414 self.roots.add(self.startrev)
2415 for parent in realparents(rev):
2416 if parent in self.roots:
2417 self.roots.add(rev)
2418 return True
2419 else:
2420 # backwards: all parents
2421 if not self.roots:
2422 self.roots.update(realparents(self.startrev))
2423 if rev in self.roots:
2424 self.roots.remove(rev)
2425 self.roots.update(realparents(rev))
2426 return True
2427
2428 return False
2429
2430
2431 2250 def walkchangerevs(repo, revs, makefilematcher, prepare):
2432 2251 '''Iterate over files and the revs in a "windowed" way.
2433 2252
@@ -776,8 +776,8 b' def _makematcher(repo, revs, wopts):'
776 776 - slowpath: True if patterns aren't as simple as scanning filelogs
777 777 """
778 778 # pats/include/exclude are passed to match.match() directly in
779 # _matchfiles() revset but walkchangerevs() builds its matcher with
780 # scmutil.match(). The difference is input pats are globbed on
779 # _matchfiles() revset, but a log-like command should build its matcher
780 # with scmutil.match(). The difference is input pats are globbed on
781 781 # platforms without shell expansion (windows).
782 782 wctx = repo[None]
783 783 match, pats = scmutil.matchandpats(wctx, wopts.pats, wopts.opts)
@@ -907,8 +907,6 b' def _makerevset(repo, wopts, slowpath):'
907 907 }
908 908
909 909 if wopts.filter_revisions_by_pats and slowpath:
910 # See walkchangerevs() slow path.
911 #
912 910 # pats/include/exclude cannot be represented as separate
913 911 # revset expressions as their filtering logic applies at file
914 912 # level. For instance "-I a -X b" matches a revision touching
General Comments 0
You need to be logged in to leave comments. Login now