Show More
@@ -136,7 +136,6 b' 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 b' 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 b' 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 b' 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 b' 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 b' 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 b' 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 |
|
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 b' 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