Mercurial > public > mercurial-scm > hg
comparison mercurial/cmdutil.py @ 22573:f528bfb25b45
revert: special case 'hg revert --all'
On large repos, hg revert --all can take over 13 seconds. This is mainly due to
it walking the tree three times: once to find the list of files in the
dirstate, once to find the list of files in the target, and once to compute the
status from the dirstate to the target.
This optimizes the hg revert --all case to only require the final status. This
speeds it up to 1.3 seconds or so (with hgwatchman enabled).
Further optimizations could be done for the -r NODE and pattern cases, but they
are significantly more complex.
author | Durham Goode <durham@fb.com> |
---|---|
date | Fri, 19 Sep 2014 18:43:53 -0700 |
parents | 8d707da26f9b |
children | cd1b43226b34 |
comparison
equal
deleted
inserted
replaced
22572:cc3d9f776632 | 22573:f528bfb25b45 |
---|---|
2478 try: | 2478 try: |
2479 ## filling of the `names` mapping | 2479 ## filling of the `names` mapping |
2480 # walk dirstate to fill `names` | 2480 # walk dirstate to fill `names` |
2481 | 2481 |
2482 m = scmutil.match(repo[None], pats, opts) | 2482 m = scmutil.match(repo[None], pats, opts) |
2483 m.bad = lambda x, y: False | 2483 if not m.always() or node != parent: |
2484 for abs in repo.walk(m): | 2484 m.bad = lambda x, y: False |
2485 names[abs] = m.rel(abs), m.exact(abs) | 2485 for abs in repo.walk(m): |
2486 | 2486 names[abs] = m.rel(abs), m.exact(abs) |
2487 # walk target manifest to fill `names` | 2487 |
2488 | 2488 # walk target manifest to fill `names` |
2489 def badfn(path, msg): | 2489 |
2490 if path in names: | 2490 def badfn(path, msg): |
2491 return | 2491 if path in names: |
2492 if path in ctx.substate: | |
2493 return | |
2494 path_ = path + '/' | |
2495 for f in names: | |
2496 if f.startswith(path_): | |
2497 return | 2492 return |
2498 ui.warn("%s: %s\n" % (m.rel(path), msg)) | 2493 if path in ctx.substate: |
2499 | 2494 return |
2500 m = scmutil.match(ctx, pats, opts) | 2495 path_ = path + '/' |
2501 m.bad = badfn | 2496 for f in names: |
2502 for abs in ctx.walk(m): | 2497 if f.startswith(path_): |
2503 if abs not in names: | 2498 return |
2504 names[abs] = m.rel(abs), m.exact(abs) | 2499 ui.warn("%s: %s\n" % (m.rel(path), msg)) |
2505 | 2500 |
2506 # Find status of all file in `names`. | 2501 m = scmutil.match(ctx, pats, opts) |
2507 m = scmutil.matchfiles(repo, names) | 2502 m.bad = badfn |
2508 | 2503 for abs in ctx.walk(m): |
2509 changes = repo.status(node1=node, match=m, | 2504 if abs not in names: |
2510 unknown=True, ignored=True, clean=True) | 2505 names[abs] = m.rel(abs), m.exact(abs) |
2506 | |
2507 # Find status of all file in `names`. | |
2508 m = scmutil.matchfiles(repo, names) | |
2509 | |
2510 changes = repo.status(node1=node, match=m, | |
2511 unknown=True, ignored=True, clean=True) | |
2512 else: | |
2513 changes = repo.status(match=m) | |
2514 for kind in changes: | |
2515 for abs in kind: | |
2516 names[abs] = m.rel(abs), m.exact(abs) | |
2517 | |
2518 m = scmutil.matchfiles(repo, names) | |
2519 | |
2511 modified = set(changes[0]) | 2520 modified = set(changes[0]) |
2512 added = set(changes[1]) | 2521 added = set(changes[1]) |
2513 removed = set(changes[2]) | 2522 removed = set(changes[2]) |
2514 _deleted = set(changes[3]) | 2523 _deleted = set(changes[3]) |
2515 unknown = set(changes[4]) | 2524 unknown = set(changes[4]) |