Patchwork [2,of,2,V2] revset: special case commonancestors(none()) to be empty set

login
register
mail settings
Submitter Yuya Nishihara
Date July 16, 2018, 10:48 a.m.
Message ID <f749aaad0d2f52e3da2a.1531738132@mimosa>
Download mbox | patch
Permalink /patch/32859/
State Accepted
Headers show

Comments

Yuya Nishihara - July 16, 2018, 10:48 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1531404449 -32400
#      Thu Jul 12 23:07:29 2018 +0900
# Node ID f749aaad0d2f52e3da2a8e80f44b798c0dd85f00
# Parent  ca00702fa0d3619554b2d17fb321fd107186c7b3
revset: special case commonancestors(none()) to be empty set

This matches the behavior of ancestor(none()).

From an implementation perspective, ancestor() and commonancestors() are
intersection, and ancestors() is union, so it would make some sense that
commonancestors(none()) returned all revisions. However, ancestor(none())
isn't implemented as such, which breaks ancestor(x) == max(commonancestors(x)).

From a user perspective, ancestors of nothing is nothing whichever type
of operation the ancestor predicate does.
Augie Fackler - July 16, 2018, 5:22 p.m.
On Mon, Jul 16, 2018 at 07:48:52PM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1531404449 -32400
> #      Thu Jul 12 23:07:29 2018 +0900
> # Node ID f749aaad0d2f52e3da2a8e80f44b798c0dd85f00
> # Parent  ca00702fa0d3619554b2d17fb321fd107186c7b3
> revset: special case commonancestors(none()) to be empty set

queued, thanks

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -632,7 +632,10 @@  def commonancestors(repo, subset, x):
 
     """
     # only wants the heads of the set passed in
-    for r in heads(repo, fullreposet(repo), x, anyorder):
+    h = heads(repo, fullreposet(repo), x, anyorder)
+    if not h:
+        return baseset()
+    for r in h:
         subset &= dagop.revancestors(repo, baseset([r]))
 
     return subset
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1063,6 +1063,12 @@  test common ancestors
   8
   9
 
+test ancestor variants of empty revision
+
+  $ log 'ancestor(none())'
+  $ log 'ancestors(none())'
+  $ log 'commonancestors(none())'
+
 test ancestors with depth limit
 
  (depth=0 selects the node itself)