Patchwork D9069: largefiles: prevent in-memory merge instead of switching to on-disk

login
register
mail settings
Submitter phabricator
Date Sept. 23, 2020, 7:13 a.m.
Message ID <differential-rev-PHID-DREV-bki54vioowuxfbgnrudn-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47242/
State Superseded
Headers show

Comments

phabricator - Sept. 23, 2020, 7:13 a.m.
martinvonz created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  I enabled in-memory merge by default while testing some changes. I
  spent quite some time troubleshooting why largefiles was still
  creating an on-disk mergestate. Then I found out that it ignores the
  callers `wc` argument to `mergemod._update()` and always uses on-disk
  merge. This patch changes that so we raise an error if largefiles is
  used with in-memory merge. That way we'll notice if in-memory merge is
  used with largefiles instead of silently replacing ignoring the
  `overlayworkingctx` instance and updating the working copy instead.
  
  I felt a little bad that this would break things more for users with
  both largefiles and in-memory rebase enabled. So I also added a
  higher-level override to make sure that largefiles disables in-memory
  rebase. It turns out that that fixes `run-tests.py -k largefiles
  --extra-config-opt rebase.experimental.inmemory=1`.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9069

AFFECTED FILES
  hgext/largefiles/__init__.py
  hgext/largefiles/overrides.py

CHANGE DETAILS




To: martinvonz, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -1103,7 +1103,7 @@ 
 
 
 @eh.wrapcommand(b'rebase', extension=b'rebase')
-def overriderebase(orig, ui, repo, **opts):
+def overriderebasecmd(orig, ui, repo, **opts):
     if not util.safehasattr(repo, b'_largefilesenabled'):
         return orig(ui, repo, **opts)
 
@@ -1111,12 +1111,30 @@ 
     repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
     repo._lfstatuswriters.append(lambda *msg, **opts: None)
     try:
-        return orig(ui, repo, **opts)
+        with ui.configoverride(
+            {(b'rebase', b'experimental.inmemory'): False}, b"largefiles"
+        ):
+            return orig(ui, repo, **opts)
     finally:
         repo._lfstatuswriters.pop()
         repo._lfcommithooks.pop()
 
 
+@eh.extsetup
+def overriderebase(ui):
+    try:
+        rebase = extensions.find(b'rebase')
+    except KeyError:
+        pass
+    else:
+
+        def _dorebase(orig, *args, **kwargs):
+            kwargs['inmemory'] = False
+            return orig(*args, **kwargs)
+
+        extensions.wrapfunction(rebase, b'_dorebase', _dorebase)
+
+
 @eh.wrapcommand(b'archive')
 def overridearchivecmd(orig, ui, repo, dest, **opts):
     with lfstatus(repo.unfiltered()):
@@ -1758,10 +1776,13 @@ 
         lfdirstate.write()
 
         oldstandins = lfutil.getstandinsstate(repo)
-        # Make sure the merge runs on disk, not in-memory. largefiles is not a
-        # good candidate for in-memory merge (large files, custom dirstate,
-        # matcher usage).
-        kwargs['wc'] = repo[None]
+        wc = kwargs.get('wc')
+        if wc and wc.isinmemory():
+            # largefiles is not a good candidate for in-memory merge (large
+            # files, custom dirstate, matcher usage).
+            raise error.ProgrammingError(
+                b'largefiles is not compatible with in-memory merge'
+            )
         result = orig(repo, node, branchmerge, force, *args, **kwargs)
 
         newstandins = lfutil.getstandinsstate(repo)
diff --git a/hgext/largefiles/__init__.py b/hgext/largefiles/__init__.py
--- a/hgext/largefiles/__init__.py
+++ b/hgext/largefiles/__init__.py
@@ -195,7 +195,9 @@ 
     for name, module in extensions.extensions():
         if name == b'rebase':
             # TODO: teach exthelper to handle this
-            extensions.wrapfunction(module, b'rebase', overrides.overriderebase)
+            extensions.wrapfunction(
+                module, b'rebase', overrides.overriderebasecmd
+            )
 
 
 revsetpredicate = eh.revsetpredicate