changeset 17185:2c7c4824969e

revset: add origin() predicate This predicate is used to find the original source of csets created by a graft, transplant or rebase --keep. If a copied cset is itself copied, only the source of the original copy is selected. hg log -r origin() # all src csets, anywhere hg log -r origin(branch(default)) # all srcs of copies on default By following through different types of copy commands and only selecting the original cset, the implementation differences between the copy commands are hidden. (A graft of a graft preserves the original source in its 'extra' map, while transplant and rebase use the immediate source specified for the command). Given a repo with a cset S that is grafted to create G(S), which itself is grafted to become G(G(S)) o-S / o-o-G(S) \ o-G(G(S)) hg log -r origin( G(S) ) # { S } hg log -r origin( G(G(S)) ) # { S }, NOT { G(S) } Even if the last graft were a transplant hg log -r origin( T(G(S)) ) # { S } A rebase without --keep essentially strips the source, so providing the cset that results to this predicate will yield an empty set. Note that the convert extension does not currently update the 'extra' map in its destination csets, and therefore copies made prior to the convert will be unable to find their source.
author Matt Harbison <matt_harbison@yahoo.com>
date Sat, 07 Jul 2012 00:47:30 -0400
parents 5fa09a3b0034
children a3da6f298592
files mercurial/revset.py tests/test-graft.t
diffstat 2 files changed, 76 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revset.py	Mon Jul 16 15:50:19 2012 +0200
+++ b/mercurial/revset.py	Sat Jul 07 00:47:30 2012 -0400
@@ -888,6 +888,34 @@
     getargs(x, 0, 0, _("obsolete takes no arguments"))
     return [r for r in subset if repo[r].obsolete()]
 
+def origin(repo, subset, x):
+    """``origin([set])``
+    Changesets that were specified as a source for the grafts, transplants or
+    rebases that created the given revisions.  Omitting the optional set is the
+    same as passing all().  If a changeset created by these operations is itself
+    specified as a source for one of these operations, only the source changeset
+    for the first operation is selected.
+    """
+    if x is not None:
+        args = set(getset(repo, range(len(repo)), x))
+    else:
+        args = set(getall(repo, range(len(repo)), x))
+
+    def _firstsrc(rev):
+        src = _getrevsource(repo, rev)
+        if src is None:
+            return None
+
+        while True:
+            prev = _getrevsource(repo, src)
+
+            if prev is None:
+                return src
+            src = prev
+
+    o = set([_firstsrc(r) for r in args])
+    return [r for r in subset if r in o]
+
 def outgoing(repo, subset, x):
     """``outgoing([path])``
     Changesets not found in the specified destination repository, or the
@@ -1392,6 +1420,7 @@
     "min": minrev,
     "modifies": modifies,
     "obsolete": obsolete,
+    "origin": origin,
     "outgoing": outgoing,
     "p1": p1,
     "p2": p2,
--- a/tests/test-graft.t	Mon Jul 16 15:50:19 2012 +0200
+++ b/tests/test-graft.t	Sat Jul 07 00:47:30 2012 -0400
@@ -358,3 +358,50 @@
   diff --git a/a b/b
   rename from a
   rename to b
+
+Test simple origin(), with and without args
+  $ hg log -r 'origin()'
+  changeset:   1:5d205f8b35b6
+  user:        bar
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     1
+  
+  changeset:   2:5c095ad7e90f
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+  changeset:   3:4c60f11aa304
+  user:        baz
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     3
+  
+  changeset:   4:9c233e8e184d
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     4
+  
+  changeset:   5:97f8bfe72746
+  branch:      stable
+  parent:      3:4c60f11aa304
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     5
+  
+  $ hg log -r 'origin(7)'
+  changeset:   2:5c095ad7e90f
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+  
+Now transplant a graft to test following through copies
+  $ hg up -q 0
+  $ hg branch -q dev
+  $ hg ci -qm "dev branch"
+  $ hg --config extensions.transplant= transplant -q 7
+  $ hg log -r 'origin(.)'
+  changeset:   2:5c095ad7e90f
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2
+