commands.revert: don't call hg.revert
commands.revert calculates everything that has to be done and then
calls hg.revert to checkout and remove files. Unfortunately,
hg.revert has to recalculate everything and that can take a long
while, since it always operates on the whole working dir.
Changing commands.revert to manually checkout and remove files
makes things considerably faster, especially if we're reverting
a single file in a repo with a huge number of files.
This should be enough to close
issue857.
--- a/mercurial/commands.py Thu Feb 14 18:08:16 2008 -0200
+++ b/mercurial/commands.py Thu Feb 14 18:08:16 2008 -0200
@@ -2251,7 +2251,6 @@
remove = ([], _('removing %s\n'))
forget = ([], _('forgetting %s\n'))
undelete = ([], _('undeleting %s\n'))
- update = {}
disptable = (
# dispatch table:
@@ -2274,7 +2273,6 @@
target = repo.wjoin(abs)
def handle(xlist, dobackup):
xlist[0].append(abs)
- update[abs] = 1
if dobackup and not opts['no_backup'] and util.lexists(target):
bakname = "%s.orig" % rel
ui.note(_('saving current version of %s as %s\n') %
@@ -2317,16 +2315,32 @@
handle(remove, False)
if not opts.get('dry_run'):
+ def checkout(f):
+ fc = ctx[f]
+ repo.wwrite(f, fc.data(), fc.fileflags())
+
for f in forget[0]:
repo.dirstate.forget(f)
- r = hg.revert(repo, node, update.has_key)
+
+ for f in revert[0]:
+ checkout(f)
+
for f in add[0]:
+ checkout(f)
repo.dirstate.add(f)
+
for f in undelete[0]:
+ checkout(f)
repo.dirstate.normal(f)
+
+ audit_path = util.path_auditor(repo.root)
for f in remove[0]:
+ audit_path(f)
+ try:
+ util.unlink(repo.wjoin(f))
+ except OSError:
+ pass
repo.dirstate.remove(f)
- return r
finally:
del wlock
--- a/tests/test-revert.out Thu Feb 14 18:08:16 2008 -0200
+++ b/tests/test-revert.out Thu Feb 14 18:08:16 2008 -0200
@@ -26,8 +26,6 @@
%% should verbosely save backup to e.orig
saving current version of e as e.orig
reverting e
-resolving manifests
-getting e
%% should say no changes needed
no changes needed to a
%% should say file not managed