changeset 20275:2123d27ff75d

backout: avoid update on simple case. Before the changeset the backout process was: 1) go to <target> 2) revert to <target> parent 3) update back to changeset we came from The two update steps can takes a very long time to move back and forth unrelated file change between <target> and current working directory. The new process is just merging current working directory with the parent of <target> using <target> as ancestor. This give the very same result but skip the two updates. On big repo with a lot of files and changes that save a lots of time (x20 for one week window). The "merge" version (hg backout --merge) is still done with upgrades. We could imagine using in memory commit to speed it up but this is another fish.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 08 Jan 2014 14:53:46 -0800
parents 7a259dfe24f7
children 6545770bd379
files mercurial/commands.py tests/test-backout.t tests/test-subrepo.t
diffstat 3 files changed, 12 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py	Thu Jan 16 12:08:57 2014 +0100
+++ b/mercurial/commands.py	Wed Jan 08 14:53:46 2014 -0800
@@ -461,16 +461,23 @@
     try:
         branch = repo.dirstate.branch()
         bheads = repo.branchheads(branch)
-        hg.clean(repo, node, show_stats=False)
-        repo.dirstate.setbranch(branch)
         rctx = scmutil.revsingle(repo, hex(parent))
-        cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
         if not opts.get('merge') and op1 != node:
             try:
                 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
-                return hg.update(repo, op1)
+                stats = mergemod.update(repo, parent, True, True, False, node, False)
+                repo.setparents(op1, op2)
+                hg._showstats(repo, stats)
+                if stats[3]:
+                    repo.ui.status(_("use 'hg resolve' to retry unresolved file merges\n"))
+                return stats[3] > 0
             finally:
                 ui.setconfig('ui', 'forcemerge', '')
+        else:
+            hg.clean(repo, node, show_stats=False)
+            repo.dirstate.setbranch(branch)
+            cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
+
 
         e = cmdutil.commiteditor
         if not opts['message'] and not opts['logfile']:
--- a/tests/test-backout.t	Thu Jan 16 12:08:57 2014 +0100
+++ b/tests/test-backout.t	Wed Jan 08 14:53:46 2014 -0800
@@ -188,7 +188,6 @@
 
 without --merge
   $ hg backout -d '3 0' 1 --tool=true
-  reverting a
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg locate b
   b
@@ -324,8 +323,7 @@
 
 without --merge
   $ hg backout -r 1 --tool=true
-  removing file1
-  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg branch
   branch2
   $ hg status -A
--- a/tests/test-subrepo.t	Thu Jan 16 12:08:57 2014 +0100
+++ b/tests/test-subrepo.t	Wed Jan 08 14:53:46 2014 -0800
@@ -468,11 +468,6 @@
 KeyError
 
   $ hg backout ".^"
-  reverting .hgsubstate
-  reverting subrepo s
-  reverting s/a (glob)
-  reverting subrepo ss
-  reverting subrepo t
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ hg up -C # discard changes