topic: introduce a 'ngtip' concept
authorPierre-Yves David <pierre-yves.david@fb.com>
Wed, 21 Oct 2015 01:12:32 +0200
changeset 1870 8dd5200b4086
parent 1869 995617c7f2fc
child 1871 58ef5699fb35
topic: introduce a 'ngtip' concept The concept is to be massively used in naming and default destination logic. The name is horrible so that people find a better one.
src/topic/destination.py
src/topic/revset.py
tests/test-topic-dest.t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/topic/destination.py	Wed Oct 21 01:12:32 2015 +0200
@@ -0,0 +1,19 @@
+from mercurial import revset
+from mercurial import error
+def ngtip(repo, branch, all=False):
+    """tip new generation"""
+    ## search for untopiced heads of branch
+    # could be heads((::branch(x) - topic()))
+    # but that is expensive
+    #
+    # we should write plain code instead
+    subquery = '''heads(
+                    parents(
+                       ancestor(
+                         (head() and branch(%s)
+                         or (topic() and branch(%s)))))
+                   ::(head() and branch(%s))
+                   - topic())'''
+    if not all:
+        subquery = 'max(%s)' % subquery
+    return repo.revs(subquery, branch, branch, branch)
--- a/src/topic/revset.py	Thu Oct 08 21:09:47 2015 -0700
+++ b/src/topic/revset.py	Wed Oct 21 01:12:32 2015 +0200
@@ -1,7 +1,7 @@
 from mercurial import revset
 from mercurial import util
 
-from . import constants
+from . import constants, destination
 
 try:
     mkmatcher = revset._stringmatcher
@@ -31,5 +31,20 @@
     return drafts.filter(
         lambda r: matcher(repo[r].extra().get(constants.extrakey, '')))
 
+def ngtipset(repo, subset, x):
+    """`ngtip([branch])`
+
+    The untopiced tip.
+
+    Name is horrible so that people change it.
+    """
+    args = revset.getargs(x, 1, 1, 'topic takes one')
+    # match a specific topic
+    branch = revset.getstring(args[0], 'ngtip() argument must be a string')
+    if branch == '.':
+        branch = repo['.'].branch()
+    return subset & destination.ngtip(repo, branch)
+
 def modsetup():
     revset.symbols.update({'topic': topicset})
+    revset.symbols.update({'ngtip': ngtipset})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-topic-dest.t	Wed Oct 21 01:12:32 2015 +0200
@@ -0,0 +1,93 @@
+  $ . "$TESTDIR/testlib"
+
+  $ hg init jungle
+  $ cd jungle
+  $ cat <<EOF >> .hg/hgrc
+  > [extensions]
+  > rebase=
+  > [phases]
+  > publish=false
+  > [ui]
+  > logtemplate = '{rev} ({topics}) {desc}\n'
+  > EOF
+
+  $ for x in alpha beta gamma delta ; do
+  >   echo file $x >> $x
+  >   hg add $x
+  >   hg ci -m "c_$x"
+  > done
+
+Test NGTip feature
+==================
+
+Simple linear case
+
+  $ echo babar >> jungle
+  $ hg add jungle
+  $ hg ci -t elephant -m babar
+
+  $ hg log -G
+  @  4 (elephant) babar
+  |
+  o  3 () c_delta
+  |
+  o  2 () c_gamma
+  |
+  o  1 () c_beta
+  |
+  o  0 () c_alpha
+  
+  $ hg log -r 'ngtip(.)'
+  3 () c_delta
+
+
+multiple heads with topic
+
+  $ hg up "desc('c_beta')"
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ echo zephir >> jungle
+  $ hg add jungle
+  $ hg ci -t monkey -m zephir
+  created new head
+  $ hg log -G
+  @  5 (monkey) zephir
+  |
+  | o  4 (elephant) babar
+  | |
+  | o  3 () c_delta
+  | |
+  | o  2 () c_gamma
+  |/
+  o  1 () c_beta
+  |
+  o  0 () c_alpha
+  
+  $ hg log -r 'ngtip(.)'
+  3 () c_delta
+
+one of the head is a valid tip
+
+  $ hg up "desc('c_delta')"
+  2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo epsilon >> epsilon
+  $ hg add epsilon
+  $ hg ci -m "c_epsilon"
+  created new head
+  $ hg log -G
+  @  6 () c_epsilon
+  |
+  | o  5 (monkey) zephir
+  | |
+  +---o  4 (elephant) babar
+  | |
+  o |  3 () c_delta
+  | |
+  o |  2 () c_gamma
+  |/
+  o  1 () c_beta
+  |
+  o  0 () c_alpha
+  
+  $ hg log -r 'ngtip(.)'
+  6 () c_epsilon
+