Patchwork [09,of,12] basectx: copy localrepo.status method

login
register
mail settings
Submitter Sean Farley
Date May 19, 2014, 8:32 p.m.
Message ID <616777bf8bd5dde9ba15.1400531536@laptop.local>
Download mbox | patch
Permalink /patch/4811/
State Accepted
Commit 9e4567829129e2e8e97a8f4b7fcd47ea0572380f
Headers show

Comments

Sean Farley - May 19, 2014, 8:32 p.m.
# HG changeset patch
# User Sean Farley <sean.michael.farley@gmail.com>
# Date 1398380862 18000
#      Thu Apr 24 18:07:42 2014 -0500
# Node ID 616777bf8bd5dde9ba157e674a6236711bf978a6
# Parent  86a5c60bb57240bf7af9b7cddfb88e354de4cc1f
basectx: copy localrepo.status method

Now that all the pieces are in place, we copy the status method from
localrepo. In the next few patches, we will remove the old implementation.

Patch

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -267,10 +267,70 @@  class basectx(object):
         return self._dirs
 
     def dirty(self):
         return False
 
+    def status(self, other=None, match=None, listignored=False,
+               listclean=False, listunknown=False, listsubrepos=False):
+        """return status of files between two nodes or node and working
+        directory.
+
+        If other is None, compare this node with working directory.
+        """
+
+        ctx1 = self
+        ctx2 = self._repo[other]
+
+        # This next code block is, admittedly, fragile logic that tests for
+        # reversing the contexts and wouldn't need to exist if it weren't for
+        # the fast (and common) code path of comparing the working directory
+        # with its first parent.
+        #
+        # What we're aiming for here is the ability to call:
+        #
+        # workingctx.status(parentctx)
+        #
+        # If we always built the manifest for each context and compared those,
+        # then we'd be done. But the special case of the above call means we
+        # just copy the manifest of the parent.
+        reversed = False
+        if (not isinstance(ctx1, changectx)
+            and isinstance(ctx2, changectx)):
+            reversed = True
+            ctx1, ctx2 = ctx2, ctx1
+
+        r = [[], [], [], [], [], [], []]
+        match = ctx2._matchstatus(ctx1, r, match, listignored, listclean,
+                                  listunknown)
+        r = ctx2._prestatus(ctx1, r, match, listignored, listclean, listunknown)
+        r = ctx2._generatestatus(ctx1, r, match, listignored, listclean,
+                                 listunknown)
+        r = ctx2._poststatus(ctx1, r, match, listignored, listclean,
+                             listunknown)
+
+        if reversed:
+            r[1], r[2], r[3], r[4] = r[2], r[1], r[4], r[3]
+
+        if listsubrepos:
+            for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
+                rev2 = ctx2.subrev(subpath)
+                try:
+                    submatch = matchmod.narrowmatcher(subpath, match)
+                    s = sub.status(rev2, match=submatch, ignored=listignored,
+                                   clean=listclean, unknown=listunknown,
+                                   listsubrepos=True)
+                    for rfiles, sfiles in zip(r, s):
+                        rfiles.extend("%s/%s" % (subpath, f) for f in sfiles)
+                except error.LookupError:
+                    self._repo.ui.status(_("skipping missing "
+                                           "subrepository: %s\n") % subpath)
+
+        for l in r:
+            l.sort()
+        return r
+
+
 def makememctx(repo, parents, text, user, date, branch, files, store,
                editor=None):
     def getfilectx(repo, memctx, path):
         data, (islink, isexec), copied = store.getfile(path)
         return memfilectx(path, data, islink=islink, isexec=isexec,