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 |
|
|
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