[PATCH 3 of 8 V2] revset: add origin() predicate

Matt Harbison matt_harbison at yahoo.com
Thu Jun 7 23:58:21 CDT 2012


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1337140860 14400
# Node ID 9eb8327a534e2f16d66b036771ebaceac93d4b2a
# Parent  356bb037ddc0c9ee510cb46e379bc715bce9e139
revset: add origin() predicate

This predicate is used to find csets that were created because of a graft,
transplant or rebase --keep with the parent of the working directory as the
source.  An optional set of csets can be supplied, in which case they will be
used as the source(s) instead.

    hg log -r origin()                 # csets copied from parent of working dir
    hg log -r origin(all())            # csets copied from anywhere
    hg log -r origin(branch(default))  # all csets copied from default

Sources of grafts are transitive due to the implementation of graft, which
maintains the same source value in 'extra' when grafting a previously grafted
cset.  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( S )    # { G(S), G(G(S)) }, NOT { G(S) }
    hg log -r origin( G(S) ) # { }

Sources of transplants and rebases, or combinations of {graft|rebase|transplant}
are not naturally transitive, due to their implementation NOT preserving the
previous source marker.  While graft preserves the source marker it left, it
does not preserve the marker when grafting a transplant or rebase.  For example

    o-S
   /
  o-o-T(S)
   \
    o-T(T(S))

    hg log -r origin( S )    # { T(S) }, NOT { T(S), T(T(S)) }
    hg log -r origin( T(S) ) # { T(T(S)) }

Rebase is a special case, because it is not possible to rebase --keep a cset
that that has itself been created because of a rebase --keep.

Note that the convert extension does not update the 'extra' map in its
destination csets, and therefore copies made prior to the convert will be
missing from the resulting set.

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -878,6 +878,18 @@
 
     return [r for r in subset if r == rn]
 
+def origin(repo, subset, x):
+    """``origin([set])``
+    Changesets that were grafted, transplanted or rebased from the given
+    revisions, or the parent of the working directory.
+    """
+    if x:
+        s = getset(repo, subset, x)
+    else:
+        s = tuple(p.rev() for p in repo[None].parents())
+
+    return [r for r in xrange(0, len(repo)) if _getrevsource(repo, r) in s]
+
 def outgoing(repo, subset, x):
     """``outgoing([path])``
     Changesets not found in the specified destination repository, or the
@@ -1360,6 +1372,7 @@
     "merge": merge,
     "min": minrev,
     "modifies": modifies,
+    "origin": origin,
     "outgoing": outgoing,
     "p1": p1,
     "p2": p2,
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -804,3 +804,160 @@
   3
 
   $ cd ..
+
+  $ hg init repo2
+  $ cd repo2
+
+  $ echo a > a
+  $ hg ci -Ama
+  adding a
+  $ hg up 0
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg branch b1
+  marked working directory as branch b1
+  (branches are permanent and global, did you want a bookmark?)
+  $ hg ci -m b1
+  $ echo s1 > s1
+  $ hg ci -Am "graft src"
+  adding s1
+  $ hg tag graft_origin
+  $ echo s2 > s2
+  $ hg ci -Am "transplant src"
+  adding s2
+  $ hg tag tp_origin
+  $ echo s3 > s3
+  $ hg ci -Am "rebase src"
+  adding s3
+  $ hg tag rebase_origin
+
+  $ hg up 0
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ hg branch b2
+  marked working directory as branch b2
+  (branches are permanent and global, did you want a bookmark?)
+  $ hg ci -m b2
+  $ hg graft graft_origin
+  grafting revision 2
+  $ hg --config extensions.transplant= transplant tp_origin
+  applying 3a74c3d1dc16
+  3a74c3d1dc16 transplanted to 9dc2dd8ef04a
+  $ hg --config extensions.rebase= rebase --keep -s  "rebase_origin"
+  $ hg tag -r '.^' rebase1
+  $ hg tag -r '.^^^^' graft1
+  $ hg tag -r '.^^^^' tp1
+
+  $ hg up default
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ hg graft graft1
+  grafting revision 9
+  $ hg tag graft2
+  $ hg --config extensions.transplant= transplant tp1
+  applying 9dc2dd8ef04a
+  9dc2dd8ef04a transplanted to 7e3d7b573a92
+  $ hg tag tp2
+
+errors out with 3 parents
+#  $ hg --config extensions.rebase= rebase --keep -s "rebase1"
+#  $ hg tag rebase2
+
+setup csets that have mixed copy types to the origin
+  $ hg up 0
+  0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+  $ hg branch b3
+  marked working directory as branch b3
+  (branches are permanent and global, did you want a bookmark?)
+  $ hg ci -m b2
+  $ hg graft tp2
+  grafting revision 18
+  $ hg tag grafted_transplant
+  $ hg --config extensions.transplant= transplant graft2
+  applying 181b4cc9a9ed
+  181b4cc9a9ed transplanted to 72b482e582db
+  $ hg tag transplanted_graft
+
+
+  $ hg log -r "origin(branch(b1))"
+  changeset:   9:7610ec1f7794
+  branch:      b2
+  tag:         graft1
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     graft src
+  
+  changeset:   10:9dc2dd8ef04a
+  branch:      b2
+  tag:         tp1
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     transplant src
+  
+  changeset:   11:c370d648cc65
+  branch:      b2
+  tag:         rebase1
+  parent:      10:9dc2dd8ef04a
+  parent:      5:40fc8932f3d8
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     rebase src
+  
+  changeset:   12:75ffd482453b
+  branch:      b2
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     Added tag rebase_origin for changeset b2f0b3dc5301
+  
+  changeset:   16:181b4cc9a9ed
+  tag:         graft2
+  parent:      0:cb9a9f314b8b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     graft src
+  
+
+  $ hg log -r "origin(tagged(graft_origin))"
+  changeset:   9:7610ec1f7794
+  branch:      b2
+  tag:         graft1
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     graft src
+  
+  changeset:   16:181b4cc9a9ed
+  tag:         graft2
+  parent:      0:cb9a9f314b8b
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     graft src
+  
+  $ hg log -r "origin(tagged(tp_origin))"
+  changeset:   10:9dc2dd8ef04a
+  branch:      b2
+  tag:         tp1
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     transplant src
+  
+
+  $ hg log -r "origin(tagged(graft1))"
+
+  $ hg log -r "origin(tagged(tp1))"
+  changeset:   18:7e3d7b573a92
+  tag:         tp2
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     transplant src
+  
+
+  $ hg up rebase_origin
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg log -r "origin()"
+  changeset:   11:c370d648cc65
+  branch:      b2
+  tag:         rebase1
+  parent:      10:9dc2dd8ef04a
+  parent:      5:40fc8932f3d8
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     rebase src
+  
+  $ cd ..
diff --git a/tests/test-transplant.t b/tests/test-transplant.t
--- a/tests/test-transplant.t
+++ b/tests/test-transplant.t
@@ -68,6 +68,7 @@
   6  b2
   7  b3
   $ hg help revsets | grep transplanted
+        Changesets that were grafted, transplanted or rebased from the given
       "transplanted([set])"
         Transplanted changesets in set, or all transplanted changesets.
 


More information about the Mercurial-devel mailing list