pushhead() now optionally takes an argument
authorGregory Szorc <gps@mozilla.com>
Fri, 08 Nov 2013 08:32:27 -0800
changeset 69 1af548d52f11c1da60f242b7c44571b186e1f4cb
parent 68 1a0274f1ff870879696d163639630a08f68718b3
child 70 cbc08bc115936d4ccfb766aa518782db83f855f7
push id50
push usergszorc@mozilla.com
push dateFri, 08 Nov 2013 17:08:44 +0000
pushhead() now optionally takes an argument
__init__.py
--- a/__init__.py
+++ b/__init__.py
@@ -126,18 +126,18 @@ me()
 
    Currently, this only retrieves changesets you authored (via ui.username).
    In the future, this extension will index review syntax in commit messages
    and return changesets that you reviewed.
 
 nobug()
    Retrieve changesets that don't reference a bug in the commit message.
 
-pushhead(TREE)
-   Retrieve changesets that are push heads for a given tree.
+pushhead([TREE])
+   Retrieve changesets that are push heads.
 
 firstpushtree(TREE)
    Retrieve changesets that initially landed on the specified tree.
 
 tree(TREE)
    Retrieve changesets that are currently in the specified tree.
 
    Trees are specified with a known alias. e.g. ``tree(central)``.
@@ -780,33 +780,55 @@ def revset_firstpushtree(repo, subset, x
         if not pushes:
             continue
 
         if pushes[0][0] == tree:
             yield rev
 
 
 def revset_pushhead(repo, subset, x):
-    """``pushhead(TREE)``
+    """``pushhead([TREE])``
     Changesets that are push heads.
 
     A push head is a changeset that was a head when it was pushed to a
     repository. In other words, the automation infrastructure likely
     kicked off a build using this changeset.
+
+    If an argument is given, we limit ourselves to pushes on the specified
+    tree.
+
+    If no argument is given, we return all push heads for all trees. Note that
+    a changeset can be a push head multiple times. This function doesn't care
+    where the push was made if no argument was given.
     """
-    tree = revset.getstring(x, _('pushhead() requires a string argument.'))
-    tree, uri = resolve_trees_to_uris([tree])[0]
+    # We have separate code paths because the single tree path uses a single
+    # query and is faster.
+    if x:
+        tree = revset.getstring(x, _('pushhead() requires a string argument.'))
+        tree, uri = resolve_trees_to_uris([tree])[0]
+
+        if not uri:
+            raise util.Abort(_("Don't know about tree: %s") % tree)
 
-    if not uri:
-        raise util.Abort(_("Don't know about tree: %s") % tree)
+        heads = set(repo[r[4]].rev() for r in
+            repo.changetracker.tree_push_heads(tree))
+
+        for r in subset:
+            if r in heads:
+                yield r
 
-    heads = set(repo[r[4]].rev() for r in
-        repo.changetracker.tree_push_heads(tree))
+        return
+
+    for r in subset:
+        node = repo[r].node()
 
-    return [r for r in subset if r in heads]
+        for push in repo.changetracker.pushes_for_changeset(node):
+            if str(push[4]) == node:
+                yield r
+                break
 
 
 def template_bug(repo, ctx, **args):
     """:bug: String. The bug this changeset is most associated with."""
     bugs = parse_bugs(ctx.description())
     return bugs[0] if bugs else None