##// 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 from mercurial.pycompat import open
136 from mercurial import (
136 from mercurial import (
137 changegroup,
137 changegroup,
138 changelog,
138 changelog,
139 cmdutil,
140 commands,
139 commands,
141 configitems,
140 configitems,
142 context,
141 context,
@@ -341,7 +340,6 def uisetup(ui):
341 extensions.wrapfunction(scmutil, b'getrenamedfn', getrenamedfn)
340 extensions.wrapfunction(scmutil, b'getrenamedfn', getrenamedfn)
342 extensions.wrapfunction(revset, b'filelog', filelogrevset)
341 extensions.wrapfunction(revset, b'filelog', filelogrevset)
343 revset.symbols[b'filelog'] = revset.filelog
342 revset.symbols[b'filelog'] = revset.filelog
344 extensions.wrapfunction(cmdutil, b'walkfilerevs', walkfilerevs)
345
343
346
344
347 def cloneshallow(orig, ui, repo, *args, **opts):
345 def cloneshallow(orig, ui, repo, *args, **opts):
@@ -782,40 +780,6 def getrenamedfn(orig, repo, endrev=None
782 return getrenamed
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 def filelogrevset(orig, repo, subset, x):
783 def filelogrevset(orig, repo, subset, x):
820 """``filelog(pattern)``
784 """``filelog(pattern)``
821 Changesets connected to the specified filelog.
785 Changesets connected to the specified filelog.
@@ -16,7 +16,6 from .i18n import _
16 from .node import (
16 from .node import (
17 hex,
17 hex,
18 nullid,
18 nullid,
19 nullrev,
20 short,
19 short,
21 )
20 )
22 from .pycompat import (
21 from .pycompat import (
@@ -49,7 +48,6 from . import (
49 revlog,
48 revlog,
50 rewriteutil,
49 rewriteutil,
51 scmutil,
50 scmutil,
52 smartset,
53 state as statemod,
51 state as statemod,
54 subrepoutil,
52 subrepoutil,
55 templatekw,
53 templatekw,
@@ -2249,185 +2247,6 def increasingwindows(windowsize=8, size
2249 windowsize *= 2
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 def walkchangerevs(repo, revs, makefilematcher, prepare):
2250 def walkchangerevs(repo, revs, makefilematcher, prepare):
2432 '''Iterate over files and the revs in a "windowed" way.
2251 '''Iterate over files and the revs in a "windowed" way.
2433
2252
@@ -776,8 +776,8 def _makematcher(repo, revs, wopts):
776 - slowpath: True if patterns aren't as simple as scanning filelogs
776 - slowpath: True if patterns aren't as simple as scanning filelogs
777 """
777 """
778 # pats/include/exclude are passed to match.match() directly in
778 # pats/include/exclude are passed to match.match() directly in
779 # _matchfiles() revset but walkchangerevs() builds its matcher with
779 # _matchfiles() revset, but a log-like command should build its matcher
780 # scmutil.match(). The difference is input pats are globbed on
780 # with scmutil.match(). The difference is input pats are globbed on
781 # platforms without shell expansion (windows).
781 # platforms without shell expansion (windows).
782 wctx = repo[None]
782 wctx = repo[None]
783 match, pats = scmutil.matchandpats(wctx, wopts.pats, wopts.opts)
783 match, pats = scmutil.matchandpats(wctx, wopts.pats, wopts.opts)
@@ -907,8 +907,6 def _makerevset(repo, wopts, slowpath):
907 }
907 }
908
908
909 if wopts.filter_revisions_by_pats and slowpath:
909 if wopts.filter_revisions_by_pats and slowpath:
910 # See walkchangerevs() slow path.
911 #
912 # pats/include/exclude cannot be represented as separate
910 # pats/include/exclude cannot be represented as separate
913 # revset expressions as their filtering logic applies at file
911 # revset expressions as their filtering logic applies at file
914 # level. For instance "-I a -X b" matches a revision touching
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