[PATCH 4 of 5 RFC] revset: add a predicate for finding rebased changesets

Matt Harbison matt_harbison at yahoo.com
Mon May 14 00:30:02 CDT 2012


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1336884852 14400
# Node ID 5de639cd52e36c27b4c8bbbaa5fdb44803efee72
# Parent  2612b6d41579adce0df8f6b744f2879868125b5b
revset: add a predicate for finding rebased changesets

This selects changesets added because of rebases.  If a revision is specified,
the set will be empty if that revision is not the source of a rebase, or it
will contain a destination changeset for each time the specified revision was
rebased.  This can be useful for figuring out where a particular changeset has
been propagated.

The source revision may be a local identifier, the short changeset hash or the
full hash.  The revision does not have to exist, since rebase may not --keep
the source.  In this case, the provided revision is matched against the
beginning of the full hashes that are stored on rebased changesets.

[Is the try/except acceptable to fallback?  Should it be done for the others
in case of strip?]

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -11,6 +11,7 @@
 import bookmarks as bookmarksmod
 import match as matchmod
 from i18n import _
+from mercurial.error import RepoLookupError
 import encoding
 import binascii
 
@@ -899,6 +900,30 @@
     pc = repo._phasecache
     return [r for r in subset if pc.phase(repo, r) == phases.public]
 
+def rebaseof(repo, subset, x):
+    """``rebaseof([rev])``
+    Changesets rebased from rev, or all rebased changesets.
+    """
+
+    # i18n: "rebaseof" is a keyword
+    l = getargs(x, 0, 1, _('rebaseof takes one or no arguments'))
+
+    # If --keep wasn't specified to rebase, or if the source was later stripped,
+    # the lookup will fail.  In this case matching based on the string is a last
+    # ditch effort.
+    try:
+        # i18n: "rebaseof" is a keyword
+        rev = l and getrev(repo, l[0], _('rebaseof requires a revision')) or None
+    except RepoLookupError:
+        rev = l[0]
+
+    def _matchvalue(r):
+        source = repo[r].extra().get('rebase_source', None)
+        # startswith instead of = in case the rev could not be resolved
+        return source is not None and (rev is None or source.startswith(rev))
+
+    return [r for r in subset if _matchvalue(r)]
+
 def remote(repo, subset, x):
     """``remote([id [,path]])``
     Local revision that corresponds to the given identifier in a
@@ -1235,6 +1260,7 @@
     "parents": parents,
     "present": present,
     "public": public,
+    "rebaseof": rebaseof,
     "remote": remote,
     "removes": removes,
     "rev": rev,


More information about the Mercurial-devel mailing list