Patchwork [1,of,2,V2] stack: take getstack() and turn it into stack class (API)

login
register
mail settings
Submitter Anton Shestakov
Date Sept. 25, 2019, 9:58 a.m.
Message ID <2c9d35029c27f3d0e63a.1569405525@df1>
Download mbox | patch
Permalink /patch/41751/
State New
Headers show

Comments

Anton Shestakov - Sept. 25, 2019, 9:58 a.m.
# HG changeset patch
# User Anton Shestakov <av6@dwimlabs.net>
# Date 1569138369 -25200
#      Sun Sep 22 14:46:09 2019 +0700
# Node ID 2c9d35029c27f3d0e63afc8f618268f079f337c3
# Parent  763028fc6a69a772cfa03c85262e2b6a439de5ab
# EXP-Topic stack-object
stack: take getstack() and turn it into stack class (API)

Stack used to be just a set of revisions, but it's going to grow more features
and it makes sense to encapsulate them into an object.

One reason we don't make stack class inherit from something like smartset class
(and be an iterable containing stack revisions) is that there's going to be
another property related to revisions and we don't want any ambiguity.

Patch

diff --git a/mercurial/destutil.py b/mercurial/destutil.py
--- a/mercurial/destutil.py
+++ b/mercurial/destutil.py
@@ -13,7 +13,7 @@  from . import (
     error,
     obsutil,
     scmutil,
-    stack
+    stack as stackmod,
 )
 
 def orphanpossibledestination(repo, rev):
@@ -378,7 +378,7 @@  def desthistedit(ui, repo):
     default = ui.config('histedit', 'defaultrev')
 
     if default is None:
-        revs = stack.getstack(repo)
+        revs = stackmod.stack(repo).revs
     elif default:
         revs = scmutil.revrange(repo, [default])
     else:
@@ -391,7 +391,7 @@  def desthistedit(ui, repo):
     return None
 
 def stackbase(ui, repo):
-    revs = stack.getstack(repo)
+    revs = stackmod.stack(repo).revs
     return revs.first() if revs else None
 
 def _statusotherbook(ui, repo):
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1695,12 +1695,11 @@  def stack(repo, subset, x):
     parent. (EXPERIMENTAL)
     """
     if x is None:
-        stacks = stackmod.getstack(repo)
+        stacks = stackmod.stack(repo).revs
     else:
         stacks = smartset.baseset([])
         for revision in getset(repo, fullreposet(repo), x):
-            currentstack = stackmod.getstack(repo, revision)
-            stacks = stacks + currentstack
+            stacks += stackmod.stack(repo, revision).revs
 
     return subset & stacks
 
diff --git a/mercurial/stack.py b/mercurial/stack.py
--- a/mercurial/stack.py
+++ b/mercurial/stack.py
@@ -7,17 +7,27 @@ 
 
 from __future__ import absolute_import
 
-def getstack(repo, rev=None):
-    """return a sorted smartrev of the stack containing either rev if it is
-    not None or the current working directory parent.
+class stack(object):
+    """Collection of revisions grouped into a stack.
 
-    The stack will always contain all drafts changesets which are ancestors to
-    the revision and are not merges.
+    The stack usually contains all drafts changesets which are ancestors to
+    the given revision and are not merges, but extensions are allowed to modify
+    stack definition (and add new methods to this class).
     """
-    if rev is None:
-        rev = '.'
+    def __init__(self, repo, rev=None):
+        """Stack object contatining either rev (if it is not None) or the
+        current working directory parent.
+        """
+        self._repo = repo
+
+        if rev is None:
+            rev = '.'
 
-    revspec = 'only(%s) and not public() and not ::merge()'
-    revisions = repo.revs(revspec, rev)
-    revisions.sort()
-    return revisions
+        revspec = 'only(%s) and not public() and not ::merge()'
+        self.revs = self._repo.revs(revspec, rev)
+        self.revs.sort()
+
+    def __nonzero__(self):
+        return bool(self.revs)
+
+    __bool__ = __nonzero__