[PATCH 03 of 17 V4] dirstate: create class for status lists

Martin von Zweigbergk martinvonz at gmail.com
Sun Oct 12 00:44:20 CDT 2014


# HG changeset patch
# User Martin von Zweigbergk <martinvonz at gmail.com>
# Date 1412976756 25200
#      Fri Oct 10 14:32:36 2014 -0700
# Node ID cd8ad3e2855507f93bc5a2fb645806c22be7b946
# Parent  7309c75e96a9a2f6d0e0f796a4d13e595e9ea958
dirstate: create class for status lists

Callers of various status() methods (on dirstate, context, repo) get a
tuple of 7 elements, where each element is a list of files. This
results in lots of uses of indexes where names would be much more
readable. For example, "status.ignored" seems clearer than "status[4]"
[1]. So, let's introduce a simple named tuple containing the 7 status
fields: modified, added, removed, deleted, unknown, ignored, clean.

This patch introduces the class and updates the status methods to
return instances of it. Later patches will update the callers.

 [1] Did you even notice that it should have been "status[5]"?

diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -11,6 +11,7 @@
 import os
 import copy
 
+from mercurial import dirstate
 from mercurial import hg, commands, util, cmdutil, scmutil, match as match_, \
         archival, pathutil, revset
 from mercurial.i18n import _
@@ -1149,7 +1150,8 @@
         modified, added, removed, deleted, unknown, ignored, clean = r
         unknown = [f for f in unknown if lfdirstate[f] == '?']
         ignored = [f for f in ignored if lfdirstate[f] == '?']
-        return modified, added, removed, deleted, unknown, ignored, clean
+        return dirstate.status(modified, added, removed, deleted, unknown,
+                               ignored, clean)
     repo.status = overridestatus
     orig(ui, repo, *dirs, **opts)
     repo.status = oldstatus
diff --git a/hgext/largefiles/reposetup.py b/hgext/largefiles/reposetup.py
--- a/hgext/largefiles/reposetup.py
+++ b/hgext/largefiles/reposetup.py
@@ -10,6 +10,7 @@
 import copy
 import os
 
+from mercurial import dirstate
 from mercurial import error, manifest, match as match_, util
 from mercurial.i18n import _
 from mercurial import localrepo
@@ -242,7 +243,7 @@
                     wlock.release()
 
             self.lfstatus = True
-            return result
+            return dirstate.status(*result)
 
         # As part of committing, copy all of the largefiles into the
         # cache.
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -7,6 +7,7 @@
 
 from node import nullid, nullrev, short, hex, bin
 from i18n import _
+import dirstate
 import mdiff, error, util, scmutil, subrepo, patch, encoding, phases
 import match as matchmod
 import os, errno, stat
@@ -340,8 +341,7 @@
         for l in r:
             l.sort()
 
-        # we return a tuple to signify that this list isn't changing
-        return tuple(r)
+        return dirstate.status(*r)
 
 
 def makememctx(repo, parents, text, user, date, branch, files, store,
@@ -1482,7 +1482,7 @@
         # (s[1] is 'added' and s[2] is 'removed')
         s = list(s)
         s[1], s[2] = s[2], s[1]
-        return tuple(s)
+        return dirstate.status(*s)
 
 class committablefilectx(basefilectx):
     """A committablefilectx provides common functionality for a file context
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -26,6 +26,50 @@
     def join(self, obj, fname):
         return obj._join(fname)
 
+class status(tuple):
+    '''Named tuple with a list of files per status. The 'deleted', 'unknown'
+       and 'ignored' properties are only relevant to the working copy.
+    '''
+
+    __slots__ = ()
+
+    def __new__(cls, modified, added, removed, deleted, unknown, ignored,
+                clean):
+        return tuple.__new__(cls, (modified, added, removed, deleted, unknown,
+                                   ignored, clean))
+
+    @property
+    def modified(self):
+        return self[0]
+
+    @property
+    def added(self):
+        return self[1]
+
+    @property
+    def removed(self):
+        return self[2]
+
+    @property
+    def deleted(self):
+        return self[3]
+
+    @property
+    def unknown(self):
+        return self[4]
+
+    @property
+    def ignored(self):
+        return self[5]
+
+    @property
+    def clean(self):
+        return self[6]
+
+    def __repr__(self, *args, **kwargs):
+        return (('<status modified=%r, added=%r, removed=%r, deleted=%r, '
+                 'unknown=%r, ignored=%r, clean=%r>') % self)
+
 class dirstate(object):
 
     def __init__(self, opener, ui, root, validate):
@@ -901,8 +945,8 @@
             elif state == 'r':
                 radd(fn)
 
-        return (lookup, (modified, added, removed, deleted, unknown, ignored,
-                         clean))
+        return (lookup, status(modified, added, removed, deleted, unknown,
+                               ignored, clean))
 
     def matches(self, match):
         '''
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -5,6 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
+import dirstate
 import errno, os, re, shutil, posixpath, sys
 import xml.dom.minidom
 import stat, subprocess, tarfile
@@ -448,7 +449,7 @@
         return 1
 
     def status(self, rev2, **opts):
-        return [], [], [], [], [], [], []
+        return dirstate.status([], [], [], [], [], [], [])
 
     def diff(self, ui, diffopts, node2, match, prefix, **opts):
         pass
@@ -650,7 +651,7 @@
         except error.RepoLookupError, inst:
             self._repo.ui.warn(_('warning: error "%s" in subrepository "%s"\n')
                                % (inst, subrelpath(self)))
-            return [], [], [], [], [], [], []
+            return dirstate.status([], [], [], [], [], [], [])
 
     @annotatesubrepoerror
     def diff(self, ui, diffopts, node2, match, prefix, **opts):
@@ -1562,7 +1563,7 @@
         rev1 = self._state[1]
         if self._gitmissing() or not rev1:
             # if the repo is missing, return no results
-            return [], [], [], [], [], [], []
+            return dirstate.status([], [], [], [], [], [], [])
         modified, added, removed = [], [], []
         self._gitupdatestat()
         if rev2:
@@ -1583,7 +1584,8 @@
                 removed.append(f)
 
         deleted = unknown = ignored = clean = []
-        return modified, added, removed, deleted, unknown, ignored, clean
+        return dirstate.status(modified, added, removed, deleted, unknown,
+                               ignored, clean)
 
     def shortid(self, revid):
         return revid[:7]
diff --git a/tests/test-context.py.out b/tests/test-context.py.out
--- a/tests/test-context.py.out
+++ b/tests/test-context.py.out
@@ -2,7 +2,7 @@
 ASCII   : Gr?ezi!
 Latin-1 : Grüezi!
 UTF-8   : Grüezi!
-(['foo'], [], [], [], [], [], [])
+<status modified=['foo'], added=[], removed=[], deleted=[], unknown=[], ignored=[], clean=[]>
 diff --git a/foo b/foo
 
 --- a/foo


More information about the Mercurial-devel mailing list