rebase: disable `inmemory` if the rebaseset contains the working copy
authorPhil Cohen <phillco@fb.com>
Fri, 08 Dec 2017 15:27:58 -0800
changeset 35332 03bec089e105
parent 35331 773a9a06047c
child 35333 8dba17546016
rebase: disable `inmemory` if the rebaseset contains the working copy As described in the comment, rebasing the working copy parent with in-memory merge, and then updating to the new commit, isn't much faster because of the extra overhead of uppdating. Best to leave it off in that case. This commit makes deploying in-memory merge via an extension easier, because you can just set `inmemory=True` based on some config or probability, and this will turn off the cases where it's not desired. Differential Revision: https://phab.mercurial-scm.org/D1616
hgext/rebase.py
--- a/hgext/rebase.py	Wed Dec 06 06:40:27 2017 +0530
+++ b/hgext/rebase.py	Fri Dec 08 15:27:58 2017 -0800
@@ -830,7 +830,8 @@
         else:
             destmap = _definedestmap(ui, repo, destf, srcf, basef, revf,
                                      destspace=destspace,
-                                     inmemory=opts['inmemory'])
+                                     opts=opts)
+            rbsrt.inmemory = opts['inmemory']
             retcode = rbsrt._preparenewrebase(destmap)
             if retcode is not None:
                 return retcode
@@ -850,7 +851,7 @@
         rbsrt._finishrebase()
 
 def _definedestmap(ui, repo, destf=None, srcf=None, basef=None, revf=None,
-                   destspace=None, inmemory=False):
+                   destspace=None, opts=None):
     """use revisions argument to define destmap {srcrev: destrev}"""
     if revf is None:
         revf = []
@@ -864,7 +865,7 @@
     if revf and srcf:
         raise error.Abort(_('cannot specify both a revision and a source'))
 
-    if not inmemory:
+    if not opts['inmemory']:
         cmdutil.checkunfinished(repo)
         cmdutil.bailifchanged(repo)
 
@@ -939,6 +940,22 @@
                 ui.status(_('nothing to rebase from %s to %s\n') %
                           ('+'.join(str(repo[r]) for r in base), dest))
             return None
+    # If rebasing the working copy parent, force in-memory merge to be off.
+    #
+    # This is because the extra work of checking out the newly rebased commit
+    # outweights the benefits of rebasing in-memory, and executing an extra
+    # update command adds a bit of overhead, so better to just do it on disk. In
+    # all other cases leave it on.
+    #
+    # Note that there are cases where this isn't true -- e.g., rebasing large
+    # stacks that include the WCP. However, I'm not yet sure where the cutoff
+    # is.
+    rebasingwcp = repo['.'].rev() in rebaseset
+    if opts['inmemory'] and rebasingwcp:
+        opts['inmemory'] = False
+        # Check these since we did not before.
+        cmdutil.checkunfinished(repo)
+        cmdutil.bailifchanged(repo)
 
     if not destf:
         dest = repo[_destrebase(repo, rebaseset, destspace=destspace)]