Patchwork [1,of,3,gca-revset,V3] revsets: add commonancestors revset

login
register
mail settings
Submitter Sean Farley
Date July 10, 2018, 12:14 a.m.
Message ID <20b61392326c251c5898.1531181667@1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa>
Download mbox | patch
Permalink /patch/32721/
State Accepted
Headers show

Comments

Sean Farley - July 10, 2018, 12:14 a.m.
# HG changeset patch
# User Sean Farley <sean@farley.io>
# Date 1529376114 25200
#      Mon Jun 18 19:41:54 2018 -0700
# Branch gca-revset
# Node ID 20b61392326c251c5898ab34a610829113e3da0b
# Parent  c153f440682f6b0d512065a915c9f4909ed05180
revsets: add commonancestors revset

This is a method to reproduce "::x and ::y" such that a set can be sent
in. For instance, it'd be convenient to have "::heads()" work like this
but that already means "::x + ::y + ..." for each element in the
"heads()" set.

Therefore, we add the "commonancestors" method to mean "::x and ::y ..."
for each head in the given set.
Yuya Nishihara - July 10, 2018, 12:18 p.m.
On Mon, 09 Jul 2018 17:14:27 -0700, Sean Farley wrote:
> # HG changeset patch
> # User Sean Farley <sean@farley.io>
> # Date 1529376114 25200
> #      Mon Jun 18 19:41:54 2018 -0700
> # Branch gca-revset
> # Node ID 20b61392326c251c5898ab34a610829113e3da0b
> # Parent  c153f440682f6b0d512065a915c9f4909ed05180
> revsets: add commonancestors revset

Queued the series, thanks.

> +@predicate('commonancestors(set)', safe=True)
> +def commonancestors(repo, subset, x):

I've moved this functions to be sorted lexicographically.
Sean Farley - July 10, 2018, 8:51 p.m.
Yuya Nishihara <yuya@tcha.org> writes:

> On Mon, 09 Jul 2018 17:14:27 -0700, Sean Farley wrote:
>> # HG changeset patch
>> # User Sean Farley <sean@farley.io>
>> # Date 1529376114 25200
>> #      Mon Jun 18 19:41:54 2018 -0700
>> # Branch gca-revset
>> # Node ID 20b61392326c251c5898ab34a610829113e3da0b
>> # Parent  c153f440682f6b0d512065a915c9f4909ed05180
>> revsets: add commonancestors revset
>
> Queued the series, thanks.
>
>> +@predicate('commonancestors(set)', safe=True)
>> +def commonancestors(repo, subset, x):
>
> I've moved this functions to be sorted lexicographically.

Ah, thanks! *dance moves begin*

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
index 7a4facb..9b9d274 100644
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -359,10 +359,26 @@  def ancestors(repo, subset, x):
             raise error.ParseError(_("negative depth"))
         stopdepth = n + 1
     return _ancestors(repo, subset, args['set'],
                       startdepth=startdepth, stopdepth=stopdepth)
 
+@predicate('commonancestors(set)', safe=True)
+def commonancestors(repo, subset, x):
+    """Returns all common ancestors of the set.
+
+    This method is for calculating "::x and ::y" (i.e. all the ancestors that
+    are common to both x and y) in an easy and optimized way. We can't quite
+    use "::head()" because that revset returns "::x + ::y + ..." for each head
+    in the repo (whereas we want "::x *and* ::y").
+
+    """
+    # only wants the heads of the set passed in
+    for r in heads(repo, fullreposet(repo), x, defineorder):
+        subset &= dagop.revancestors(repo, baseset([r]))
+
+    return subset
+
 @predicate('_firstancestors', safe=True)
 def _firstancestors(repo, subset, x):
     # ``_firstancestors(set)``
     # Like ``ancestors(set)`` but follows only the first parents.
     return _ancestors(repo, subset, x, followfirst=True)
diff --git a/tests/test-revset.t b/tests/test-revset.t
index 1fc7044..35fff85 100644
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1039,10 +1039,32 @@  test ancestors
   0
   1
   2
   3
 
+test common ancestors
+
+  $ hg log -T '{rev}\n' -r 'commonancestors(7 + 9)'
+  0
+  1
+  2
+  4
+
+  $ hg log -T '{rev}\n' -r 'commonancestors(head())'
+  0
+  1
+  2
+  4
+
+  $ hg log -T '{rev}\n' -r 'commonancestors(9)'
+  0
+  1
+  2
+  4
+  8
+  9
+
 test ancestors with depth limit
 
  (depth=0 selects the node itself)
 
   $ log 'reverse(ancestors(9, depth=0))'