Patchwork [2,of,6,V2] obsolete: drop successors sets which are subset of another one

login
register
mail settings
Submitter Pierre-Yves David
Date Dec. 13, 2012, 2:51 p.m.
Message ID <a63af12dc0cdf8e7c828.1355410309@crater1.logilab.fr>
Download mbox | patch
Permalink /patch/78/
State Accepted
Commit f84e731cbd204a08347798641d802215562bad87
Headers show

Comments

Pierre-Yves David - Dec. 13, 2012, 2:51 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1352509019 -3600
# Node ID a63af12dc0cdf8e7c828f2278427b3beea1220c2
# Parent  4eb351a0771c5cdf48b288d37fe0dc80b4ac38cb
obsolete: drop successors sets which are subset of another one

If both "(B,)" and "(B, C)" are successors set of "A", "(B,)" is dropped.
We won't be interrested in detection such divergence scenario.

Patch

diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -558,15 +558,20 @@  def successorssets(repo, initialnode, ca
                 #
                 # Within a marker, a successor may have divergent successors
                 # sets. In such a case, the marker will contribute multiple
                 # divergent successors sets. If multiple successors have
                 # divergents successors sets, a cartesien product is used.
+                #
+                # At the end we post-process successors sets to remove
+                # duplicated entry and successors set that are strict subset of
+                # another one.
                 succssets = []
                 for mark in succmarkers[current]:
                     # successors sets contributed by this marker
                     markss = [[]]
                     for suc in mark[1]:
+                        # cardinal product with previous successors
                         productresult = []
                         for prefix in markss:
                             for suffix in cache[suc]:
                                 newss = list(prefix)
                                 for part in suffix:
@@ -575,11 +580,24 @@  def successorssets(repo, initialnode, ca
                                     if part not in newss:
                                         newss.append(part)
                                 productresult.append(newss)
                         markss = productresult
                     succssets.extend(markss)
-                cache[current] = list(set(tuple(r) for r in succssets if r))
+                # remove duplicated and subset
+                seen = []
+                final = []
+                candidate = sorted(((set(s), s) for s in succssets if s),
+                                   key=lambda x: len(x[1]), reverse=True)
+                for setversion, listversion in candidate:
+                    for seenset in seen:
+                        if setversion.issubset(seenset):
+                            break
+                    else:
+                        final.append(listversion)
+                        seen.append(setversion)
+                final.reverse() # put small successors set first
+                cache[current] = final
     return cache[initialnode]
 
 def _knownrevs(repo, nodes):
     """yield revision numbers of known nodes passed in parameters
 
diff --git a/tests/test-obsolete-divergent.t b/tests/test-obsolete-divergent.t
--- a/tests/test-obsolete-divergent.t
+++ b/tests/test-obsolete-divergent.t
@@ -73,12 +73,12 @@  A_1 have two direct and divergent succes
   
   $ hg debugsuccessorssets 'all()'
   d20a80d4def3
       d20a80d4def3
   007dc284c1f8
+      392fd25390da
       82623d38b9ba
-      392fd25390da
   82623d38b9ba
       82623d38b9ba
   392fd25390da
       392fd25390da
   $ cd ..
@@ -137,12 +137,12 @@  indirect divergence with known changeset
   
   $ hg debugsuccessorssets 'all()'
   d20a80d4def3
       d20a80d4def3
   007dc284c1f8
+      392fd25390da
       82623d38b9ba
-      392fd25390da
   82623d38b9ba
       82623d38b9ba
   392fd25390da
       392fd25390da
   $ cd ..
@@ -394,5 +394,20 @@  fix the divergence
   a139f71be9da
       a139f71be9da
 
   $ cd ..
 
+
+Subset does not diverge
+------------------------------
+
+Do not report divergent successors-set if it is a subset of another
+successors-set. (report [A,B] not [A] + [A,B])
+
+  $ newcase subset
+  $ hg debugobsolete `getid A_0` `getid A_2`
+  $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
+  $ hg debugsuccessorssets 'desc('A_0')'
+  007dc284c1f8
+      82623d38b9ba 392fd25390da
+
+  $ cd ..