Commits

Pierre-Yves David committed 1a08dae

obsolete: add revset for various error case

Comments (0)

Files changed (2)

hgext/obsolete.py

 :obsolete:     a changeset that have been replace by another one.
 :unstable:     a non-obsolet changeset based on another one.
 :suspended:    an obsolete changeset with unstable descendant.
+:extinct:      an obsolete changeset without unstable descendant
+               (subject to garbage collection)
 
 Another name for unstable could be out of sync.
 
 
 
 def revsetobsolete(repo, subset, x):
-    """filter obsolet entry"""
-    args = revset.getargs(x, 0, 0, 'publicheads takes no arguments')
+    """obsolete changesets"""
+    args = revset.getargs(x, 0, 0, 'obsolete takes no argument')
     return [r for r in subset if r in repo._obsoleteset and repo._phaserev[r] > 0]
 
+def revsetunstable(repo, subset, x):
+    """non obsolete changesets descendant of obsolete one"""
+    args = revset.getargs(x, 0, 0, 'unstable takes no arguments')
+    return [r for r in subset if r in repo._unstableset]
+
+def revsetsuspended(repo, subset, x):
+    """obsolete changesets with non obsolete descendants"""
+    args = revset.getargs(x, 0, 0, 'unstable takes no arguments')
+    return [r for r in subset if r in repo._suspendedset]
+
+def revsetextinct(repo, subset, x):
+    """obsolete changesets without obsolete descendants"""
+    args = revset.getargs(x, 0, 0, 'unstable takes no arguments')
+    return [r for r in subset if r in repo._extinctset]
+
 ### Other Extension compat
 ############################
 
 def extsetup(ui):
 
     revset.symbols["obsolete"] = revsetobsolete
+    revset.symbols["unstable"] = revsetunstable
+    revset.symbols["suspended"] = revsetsuspended
+    revset.symbols["extinct"] = revsetextinct
 
 
     try:
 
         @util.propertycache
         def _obsoleteset(self):
+            """the set of obsolete revision"""
             obs = set()
             nm = self.changelog.nodemap
             for obj in self._obsobjrels:
                     obs.add(rev)
             return obs
 
+        @util.propertycache
+        def _unstableset(self):
+            """the set of non obsolete revision with obsolete parent"""
+            return set(self.revs('(obsolete()::) - obsolete()'))
+
+        @util.propertycache
+        def _suspendedset(self):
+            """the set of obsolete parent with non obsolete descendant"""
+            return set(self.revs('obsolete() and obsolete()::unstable()'))
+
+        @util.propertycache
+        def _extinctset(self):
+            """the set of obsolete parent without non obsolete descendant"""
+            return set(self.revs('obsolete() - obsolete()::unstable()'))
+
+        def _clearobsoletecache(self):
+            if '_obsobjrels' in vars(self):
+                del self._obsobjrels
+            if '_obssubrels' in vars(self):
+                del self._obssubrels
+            if '_obsoleteset' in vars(self):
+                del self._obsoleteset
+            if '_unstableset' in vars(self):
+                del self._unstableset
+            if '_suspendedset' in vars(self):
+                del self._suspendedset
+            if '_extinct' in vars(self):
+                del self._extinctset
+
         def addobsolete(self, sub, obj):
             """Add a relation marking that node <sub> is a new version of <obj>"""
             if sub == nullid:
             except (error.RepoLookupError, error.LookupError):
                 pass #unknow revision (but keep propagating the data
             self._writeobsrels()
-            if '_obsobjrels' in vars(self):
-                del self._obsobjrels
-            if '_obssubrels' in vars(self):
-                del self._obssubrels
-            if '_obsoleteset' in vars(self):
-                del self._obsoleteset
+            self._clearobsoletecache()
             return 1
 
         ### obsolete storage
 
     repo.__class__ = obsoletingrepo
     if repo.ui.configbool('obsolete', 'secret-unstable', True):
-        expobs = [c.node() for c in repo.set('obsolete() - secret()')]
-        if expobs: # do not lock in nothing move. locking for peanut make hgview reload on any command
-            lock = repo.lock()
-            try:
-                phases.retractboundary(repo, 2, expobs)
-            finally:
-                lock.release()
+        symbol = 'obsolete()'
+    else:
+        symbol = 'extinct()'
 
+    expobs = [c.node() for c in repo.set('%s - secret()' % symbol)]
+    if expobs: # do not lock in nothing move. locking for peanut make hgview reload on any command
+        lock = repo.lock()
+        try:
+            phases.retractboundary(repo, 2, expobs)
+        finally:
+            lock.release()
 
+

tests/test-obsolete.t

   > allow_push = *
   > [phases]
   > publish=False
+  > [obsolete]
+  > secret-unstable=no
   > [extensions]
   > EOF
   $ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext/obsolete.py" >> $HGRCPATH
   $ hg init local
   $ cd local
   $ mkcommit a # 0
-  $ hg pull -q . #hg published 0
+  $ hg phase -p .
   $ mkcommit b # 1
   $ mkcommit c # 2
   $ hg up 1
 Test communication of obsolete relation with a compatible client
 
   $ hg init ../other-new
+  $ hg phase --draft 'secret() - extinct()' # until we fix exclusion
   $ hg push --traceback ../other-new
   pushing to ../other-new
   searching for changes
   adding changesets
   adding manifests
   adding file changes
-  added 2 changesets with 2 changes to 2 files (+2 heads)
+  added 1 changesets with 1 changes to 1 files (+1 heads)
   (run 'hg heads .' to see heads, 'hg merge' to merge)
   $ qlog -R ../other-new
-  7
+  6
   - 909a0fb57e5d
   3
   - 725c380fe99b
   adding changesets
   adding manifests
   adding file changes
-  added 8 changesets with 8 changes to 8 files (+4 heads)
+  added 5 changesets with 5 changes to 5 files (+1 heads)
   updating to branch default
   4 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ qlog -R ../cloned
-  7
+  4
   - 909a0fb57e5d
-  4
+  3
   - 725c380fe99b
-  3
+  2
   - 0d3f46688ccc
   1
   - 7c3bad9141dc
   (run 'hg heads .' to see heads, 'hg merge' to merge)
 
   $ qlog -R ../other-new
-  8
+  7
   - 159dfc9fa5d3
   3
   - 725c380fe99b
   0
   - 1f0dee641bb7
   $ hg -R ../other-new rollback
-  repository tip rolled back to revision 7 (undo pull)
+  repository tip rolled back to revision 6 (undo pull)
   $ qlog -R ../other-new
-  7
+  6
   - 909a0fb57e5d
   3
   - 725c380fe99b
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.