changeset 6107:41bb88cb913e

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.
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Thu, 14 Feb 2008 18:08:16 -0200
parents cb2f7652ad1b
children 5086576a2152
files mercurial/commands.py tests/test-revert.out
diffstat 2 files changed, 18 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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