[PATCH 10 of 24] subrepos: process subrepos in sorted order

Mads Kiilerich mads at kiilerich.com
Sun Dec 16 16:34:05 CST 2012


# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1355276294 -3600
# Node ID 3736a972c5892ad69f851e7cdf08b835629257de
# Parent  3c6e2e0aad7fbd090bac10d2cd6589da6421556b
subrepos: process subrepos in sorted order

Add sorted() in places found by testing with PYTHONHASHSEED=random and code
inspection.

An alternative to sprinkling sorted() all over would be to change substate to a
custom dict with sorted iterators...

diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -840,7 +840,7 @@
         write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
 
     if subrepos:
-        for subpath in ctx.substate:
+        for subpath in sorted(ctx.substate):
             sub = ctx.sub(subpath)
             submatch = match_.narrowmatcher(subpath, matchfn)
             sub.archive(repo.ui, archiver, prefix, submatch)
@@ -887,7 +887,7 @@
 
         write(f, 'x' in ff and 0755 or 0644, 'l' in ff, getdata)
 
-    for subpath in ctx.substate:
+    for subpath in sorted(ctx.substate):
         sub = ctx.sub(subpath)
         submatch = match_.narrowmatcher(subpath, match)
         sub.archive(ui, archiver, os.path.join(prefix, repo._path) + '/',
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -947,7 +947,7 @@
             bctx = repo[baserev]
         else:
             bctx = wctx.parents()[0]
-        for s in wctx.substate:
+        for s in sorted(wctx.substate):
             if wctx.sub(s).dirty(True):
                 raise util.Abort(
                     _("uncommitted changes in subrepository %s") % s)
diff --git a/mercurial/archival.py b/mercurial/archival.py
--- a/mercurial/archival.py
+++ b/mercurial/archival.py
@@ -297,7 +297,7 @@
     repo.ui.progress(_('archiving'), None)
 
     if subrepos:
-        for subpath in ctx.substate:
+        for subpath in sorted(ctx.substate):
             sub = ctx.sub(subpath)
             submatch = matchmod.narrowmatcher(subpath, matchfn)
             sub.archive(repo.ui, archiver, prefix, submatch)
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -85,7 +85,7 @@
     if modified or added or removed or deleted:
         raise util.Abort(_("outstanding uncommitted changes"))
     ctx = repo[None]
-    for s in ctx.substate:
+    for s in sorted(ctx.substate):
         if ctx.sub(s).dirty():
             raise util.Abort(_("uncommitted changes in subrepo %s") % s)
 
@@ -1534,7 +1534,7 @@
             if ui.verbose or not exact:
                 ui.status(_('adding %s\n') % match.rel(join(f)))
 
-    for subpath in wctx.substate:
+    for subpath in sorted(wctx.substate):
         sub = wctx.sub(subpath)
         try:
             submatch = matchmod.narrowmatcher(subpath, match)
@@ -1565,7 +1565,7 @@
     if explicitonly:
         forget = [f for f in forget if match.exact(f)]
 
-    for subpath in wctx.substate:
+    for subpath in sorted(wctx.substate):
         sub = wctx.sub(subpath)
         try:
             submatch = matchmod.narrowmatcher(subpath, match)
@@ -1871,7 +1871,7 @@
                 names[abs] = m.rel(abs), m.exact(abs)
 
         # get the list of subrepos that must be reverted
-        targetsubs = [s for s in ctx.substate if m(s)]
+        targetsubs = sorted(s for s in ctx.substate if m(s))
         m = scmutil.matchfiles(repo, names)
         changes = repo.status(match=m)[:4]
         modified, added, removed, deleted = map(set, changes)
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -990,13 +990,13 @@
         return self._parents[0].ancestor(c2) # punt on two parents for now
 
     def walk(self, match):
-        return sorted(self._repo.dirstate.walk(match, self.substate.keys(),
+        return sorted(self._repo.dirstate.walk(match, sorted(self.substate),
                                                True, False))
 
     def dirty(self, missing=False, merge=True, branch=True):
         "check whether a working directory is modified"
         # check subrepos first
-        for s in self.substate:
+        for s in sorted(self.substate):
             if self.sub(s).dirty():
                 return True
         # check current working dir
diff --git a/mercurial/fileset.py b/mercurial/fileset.py
--- a/mercurial/fileset.py
+++ b/mercurial/fileset.py
@@ -373,7 +373,7 @@
     # i18n: "subrepo" is a keyword
     getargs(x, 0, 1, _("subrepo takes at most one argument"))
     ctx = mctx.ctx
-    sstate = ctx.substate
+    sstate = sorted(ctx.substate)
     if x:
         pat = getstring(x, _("subrepo requires a pattern or no arguments"))
 
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1612,7 +1612,7 @@
         if working: # we need to scan the working dir
             subrepos = []
             if '.hgsub' in self.dirstate:
-                subrepos = ctx2.substate.keys()
+                subrepos = sorted(ctx2.substate)
             s = self.dirstate.status(match, subrepos, listignored,
                                      listclean, listunknown)
             cmp, modified, added, removed, deleted, unknown, ignored, clean = s
diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -236,7 +236,7 @@
 
     if '.hgsubstate' in m1:
         # check whether sub state is modified
-        for s in p1.substate:
+        for s in sorted(p1.substate):
             if p1.sub(s).dirty():
                 m1['.hgsubstate'] += "+"
                 break
@@ -611,7 +611,7 @@
             if not force and (wc.files() or wc.deleted()):
                 raise util.Abort(_("outstanding uncommitted changes"),
                                  hint=_("use 'hg status' to list changes"))
-            for s in wc.substate:
+            for s in sorted(wc.substate):
                 if wc.sub(s).dirty():
                     raise util.Abort(_("outstanding uncommitted changes in "
                                        "subrepository '%s'") % s)
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -126,7 +126,7 @@
             r = "%s:%s:%s" % r
         repo.ui.debug("  subrepo %s: %s %s\n" % (s, msg, r))
 
-    for s, l in s1.items():
+    for s, l in sorted(s1.items()):
         a = sa.get(s, nullstate)
         ld = l # local state with possible dirty flag for compares
         if wctx.sub(s).dirty():
diff --git a/tests/test-subrepo-svn.t b/tests/test-subrepo-svn.t
--- a/tests/test-subrepo-svn.t
+++ b/tests/test-subrepo-svn.t
@@ -544,11 +544,11 @@
   archiving: .hgsubstate 2/2 files (100.00%)
   archiving (obstruct): 0/1 files (0.00%)
   archiving (obstruct): 1/1 files (100.00%)
+  archiving (recreated): 0/1 files (0.00%)
+  archiving (recreated): 1/1 files (100.00%)
   archiving (s): 0/2 files (0.00%)
   archiving (s): 1/2 files (50.00%)
   archiving (s): 2/2 files (100.00%)
-  archiving (recreated): 0/1 files (0.00%)
-  archiving (recreated): 1/1 files (100.00%)
 
   $ hg archive -S ../archive-exclude --debug -X **old
   archiving: 0/2 files (0.00%)
@@ -556,10 +556,10 @@
   archiving: .hgsubstate 2/2 files (100.00%)
   archiving (obstruct): 0/1 files (0.00%)
   archiving (obstruct): 1/1 files (100.00%)
+  archiving (recreated): 0 files
   archiving (s): 0/2 files (0.00%)
   archiving (s): 1/2 files (50.00%)
   archiving (s): 2/2 files (100.00%)
-  archiving (recreated): 0 files
   $ find ../archive-exclude | sort
   ../archive-exclude
   ../archive-exclude/.hg_archival.txt


More information about the Mercurial-devel mailing list