Patchwork [4,of,9] dagop: change revdescendants() to include all root revisions

login
register
mail settings
Submitter Yuya Nishihara
Date June 25, 2017, 3:26 a.m.
Message ID <71cadea3248d853fa0b2.1498361173@mimosa>
Download mbox | patch
Permalink /patch/21685/
State Accepted
Headers show

Comments

Yuya Nishihara - June 25, 2017, 3:26 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1497965212 -32400
#      Tue Jun 20 22:26:52 2017 +0900
# Node ID 71cadea3248d853fa0b297388f704ec11cc63e4c
# Parent  58530a54c89dc9de8fbb3e487f6e3af28cd3f5b4
dagop: change revdescendants() to include all root revisions

Prepares for adding depth support. I want to process depth=0 in
revdescendants() to make things simpler.

only() also calls dagop.revdescendants(), but it filters out root revisions
explicitly. So this should cause no problem.

  # descendants(0) using hg repo
  0) 0.052380
  1) 0.051226

  # only(tip) using hg repo
  0) 0.001433
  1) 0.001425

Patch

diff --git a/mercurial/dagop.py b/mercurial/dagop.py
--- a/mercurial/dagop.py
+++ b/mercurial/dagop.py
@@ -98,11 +98,15 @@  def _genrevdescendants(repo, revs, follo
     if first == nullrev:
         # Are there nodes with a null first parent and a non-null
         # second one? Maybe. Do we care? Probably not.
+        yield first
         for i in cl:
             yield i
     else:
         seen = set(revs)
-        for i in cl.revs(first + 1):
+        for i in cl.revs(first):
+            if i in seen:
+                yield i
+                continue
             for x in cl.parentrevs(i)[:cut]:
                 if x != nullrev and x in seen:
                     seen.add(i)
@@ -110,7 +114,8 @@  def _genrevdescendants(repo, revs, follo
                     break
 
 def revdescendants(repo, revs, followfirst):
-    """Like revlog.descendants() but supports followfirst."""
+    """Like revlog.descendants() but supports additional options, includes
+    the given revs themselves, and returns a smartset"""
     gen = _genrevdescendants(repo, revs, followfirst)
     return generatorset(gen, iterasc=True)
 
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -600,19 +600,7 @@  def _descendants(repo, subset, x, follow
     if not roots:
         return baseset()
     s = dagop.revdescendants(repo, roots, followfirst)
-
-    # Both sets need to be ascending in order to lazily return the union
-    # in the correct order.
-    base = subset & roots
-    desc = subset & s
-    result = base + desc
-    if subset.isascending():
-        result.sort()
-    elif subset.isdescending():
-        result.sort(reverse=True)
-    else:
-        result = subset & result
-    return result
+    return subset & s
 
 @predicate('descendants(set)', safe=True)
 def descendants(repo, subset, x):
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -3530,11 +3530,7 @@  test alias recursion
       ('symbol', 'merge')
       None))
   * set:
-  <addset+
-    <filteredset
-      <fullreposet+ 0:10>,
-      <merge>>,
-    <generatorset+>>
+  <generatorset+>
   6
   7