[PATCH 12 of 13 sparse] merge: move getsparsepatterns from sparse extension

Gregory Szorc gregory.szorc at gmail.com
Sat Jul 1 21:55:29 EDT 2017


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1498946654 25200
#      Sat Jul 01 15:04:14 2017 -0700
# Node ID ac5ef7ac57c2fb6f2a9d3ad1381e7705ebaf690f
# Parent  7d0bacb3f8bb5f8b350acfeb79802b8486fd1337
merge: move getsparsepatterns from sparse extension

This method is reasonably well-contained and simple to move.

As part of the move, some light formatting was performed.

A "working copy" reference in an error message was changed to
"working directory."

The biggest change was to _refreshoncommit() in sparse.py. It
was previously checking for the existence of an attribute on
the repo instance. Since the moved function now returns empty
data if sparse isn't enabled, we unconditionally call the
new function. However, we do have to protect another method
call in that function. This will all be unhacked eventually.

diff --git a/hgext/sparse.py b/hgext/sparse.py
--- a/hgext/sparse.py
+++ b/hgext/sparse.py
@@ -249,14 +249,17 @@ def _setupcommit(ui):
         """
         orig(self, node)
         repo = self._repo
-        if util.safehasattr(repo, 'getsparsepatterns'):
-            ctx = repo[node]
-            _, _, profiles = repo.getsparsepatterns(ctx.rev())
-            if set(profiles) & set(ctx.files()):
-                origstatus = repo.status()
-                origsparsematch = repo.sparsematch()
-                _refresh(repo.ui, repo, origstatus, origsparsematch, True)
+
+        ctx = repo[node]
+        profiles = mergemod.sparsepatterns(repo, ctx.rev())[2]
 
+        # profiles will only have data if sparse is enabled.
+        if set(profiles) & set(ctx.files()):
+            origstatus = repo.status()
+            origsparsematch = repo.sparsematch()
+            _refresh(repo.ui, repo, origstatus, origsparsematch, True)
+
+        if util.safehasattr(repo, 'prunetemporaryincludes'):
             repo.prunetemporaryincludes()
 
     extensions.wrapfunction(context.committablectx, 'markcommitted',
@@ -409,54 +412,6 @@ def _setupdirstate(ui):
 
 def _wraprepo(ui, repo):
     class SparseRepo(repo.__class__):
-        def getsparsepatterns(self, rev):
-            """Returns the include/exclude patterns specified by the
-            given rev.
-            """
-            raw = self.vfs.tryread('sparse')
-            if not raw:
-                return set(), set(), []
-            if rev is None:
-                raise error.Abort(_("cannot parse sparse patterns from " +
-                    "working copy"))
-
-            includes, excludes, profiles = mergemod.readsparseconfig(
-                self.ui, raw)
-
-            ctx = self[rev]
-            if profiles:
-                visited = set()
-                while profiles:
-                    profile = profiles.pop()
-                    if profile in visited:
-                        continue
-                    visited.add(profile)
-
-                    try:
-                        raw = mergemod.rawsparseprofile(self, profile, rev)
-                    except error.ManifestLookupError:
-                        msg = (
-                            "warning: sparse profile '%s' not found "
-                            "in rev %s - ignoring it\n" % (profile, ctx))
-                        if self.ui.configbool(
-                                'sparse', 'missingwarning', True):
-                            self.ui.warn(msg)
-                        else:
-                            self.ui.debug(msg)
-                        continue
-                    pincludes, pexcludes, subprofs = mergemod.readsparseconfig(
-                        self.ui, raw)
-                    includes.update(pincludes)
-                    excludes.update(pexcludes)
-                    for subprofile in subprofs:
-                        profiles.append(subprofile)
-
-                profiles = visited
-
-            if includes:
-                includes.add('.hg*')
-            return includes, excludes, profiles
-
         def _sparsechecksum(self, path):
             data = self.vfs.read(path)
             return hashlib.sha1(data).hexdigest()
@@ -521,7 +476,8 @@ def _wraprepo(ui, repo):
             matchers = []
             for rev in revs:
                 try:
-                    includes, excludes, profiles = self.getsparsepatterns(rev)
+                    includes, excludes, profiles = mergemod.sparsepatterns(
+                        self, rev)
 
                     if includes or excludes:
                         # Explicitly include subdirectories of includes so
@@ -566,7 +522,7 @@ def _wraprepo(ui, repo):
 
             activeprofiles = set()
             for rev in revs:
-                _, _, profiles = self.getsparsepatterns(rev)
+                _, _, profiles = mergemod.sparsepatterns(self, rev)
                 activeprofiles.update(profiles)
 
             return activeprofiles
@@ -817,7 +773,7 @@ def _import(ui, repo, files, opts, force
         # all active rules
         aincludes, aexcludes, aprofiles = set(), set(), set()
         for rev in revs:
-            rincludes, rexcludes, rprofiles = repo.getsparsepatterns(rev)
+            rincludes, rexcludes, rprofiles = mergemod.sparsepatterns(repo, rev)
             aincludes.update(rincludes)
             aexcludes.update(rexcludes)
             aprofiles.update(rprofiles)
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -1787,3 +1787,60 @@ def readsparseconfig(ui, raw):
 # Exists as separate function to facilitate monkeypatching.
 def rawsparseprofile(repo, profile, changeid):
     return repo.filectx(profile, changeid=changeid).data()
+
+def sparsepatterns(repo, rev):
+    """Obtain sparse checkout patterns for the given rev.
+
+    Returns a tuple of iterables representing includes, excludes, and
+    patterns.
+    """
+    # Feature isn't enabled. No-op.
+    if not sparseenabled:
+        return set(), set(), []
+
+    raw = repo.vfs.tryread('sparse')
+    if not raw:
+        return set(), set(), []
+
+    if rev is None:
+        raise error.Abort(_('cannot parse sparse patterns from working '
+                            'directory'))
+
+    includes, excludes, profiles = readsparseconfig(repo.ui, raw)
+    ctx = repo[rev]
+
+    if profiles:
+        visited = set()
+        while profiles:
+            profile = profiles.pop()
+            if profile in visited:
+                continue
+
+            visited.add(profile)
+
+            try:
+                raw = rawsparseprofile(repo, profile, rev)
+            except error.ManifestLookupError:
+                msg = (
+                    "warning: sparse profile '%s' not found "
+                    "in rev %s - ignoring it\n" % (profile, ctx))
+                # experimental config: sparse.missingwarning
+                if repo.ui.configbool(
+                        'sparse', 'missingwarning', True):
+                    repo.ui.warn(msg)
+                else:
+                    repo.ui.debug(msg)
+                continue
+
+            pincludes, pexcludes, subprofs = readsparseconfig(repo.ui, raw)
+            includes.update(pincludes)
+            excludes.update(pexcludes)
+            for subprofile in subprofs:
+                profiles.append(subprofile)
+
+        profiles = visited
+
+    if includes:
+        includes.add('.hg*')
+
+    return includes, excludes, profiles


More information about the Mercurial-devel mailing list