Ability to query and select basic push information
authorGregory Szorc <gps@mozilla.com>
Fri, 08 Nov 2013 00:23:02 -0800
changeset 64 05f97a21b0c18ed99f48c3cee392d031aa73d6ae
parent 63 a10db377c453387b2460da08748d9b460cb5f6f5
child 65 d4dd9768a411706c413694814e6d679cd322228c
push id45
push usergszorc@mozilla.com
push dateFri, 08 Nov 2013 08:23:09 +0000
Ability to query and select basic push information
__init__.py
--- a/__init__.py
+++ b/__init__.py
@@ -120,16 +120,19 @@ bug(BUG)
 
 me()
    Retrieve changesets that you are involved with.
 
    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.
 
+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)``.
 
    It's possible to see which changesets are in some tree but not others.
    e.g. to find changesets in *inbound* that haven't merged to *central*
    yet, do ``tree(inbound) - tree(central)``.
@@ -172,16 +175,22 @@ auroradate
    calculation involves grabbing information from release engineering
    servers.
 
 nightlydate
    The date of the first Nightly a changeset was likely present in.
 
    See auroradate for accuracy information.
 
+firstpushuser
+   The username of the first person who pushed this changeset.
+
+firstpushtree
+   The name of the first tree this changeset was pushed to.
+
 Config Options
 ==============
 
 This extension consults the following config options.
 
 mozext.headless
    Indicates that this extension is running in *headless* mode. *headless*
    mode is intended for server operation, not local development.
@@ -723,16 +732,37 @@ def revset_tree(repo, subset, x):
     ref = '%s/default' % tree
 
     head = repo[ref].rev()
     ancestors = set(repo.changelog.ancestors([head], inclusive=True))
 
     return [r for r in subset if r in ancestors]
 
 
+def revset_firstpushtree(repo, subset, x):
+    """``firstpushtree(X)``
+    Changesets that were initially pushed to tree X.
+    """
+    tree = revset.getstring(x, _('firstpushtree() 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)
+
+    for rev in subset:
+        pushes = list(repo.changetracker.pushes_for_changeset(
+            repo[rev].node()))
+
+        if not pushes:
+            continue
+
+        if pushes[0][0] == tree:
+            yield rev
+
+
 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
 
 
 def template_bugs(repo, ctx, **args):
     """:bugs: List of ints. The bugs associated with this changeset."""
@@ -858,38 +888,63 @@ def template_auroradate(repo, ctx, **arg
 
 def template_nightlydate(repo, ctx, **args):
     """:nightlydate: Date information. The date of the first Nightly this
     changeset was likely first active in as a YYYY-MM-DD value.
     """
     return _calculate_next_daily_release(repo, ctx, 'central')
 
 
+def template_firstpushuser(repo, ctx, **args):
+    """:firstpushuser: String. The first person who pushed this changeset.
+    """
+    pushes = list(repo.changetracker.pushes_for_changeset(ctx.node()))
+
+    if not pushes:
+        return None
+
+    return pushes[0][3]
+
+
+def template_firstpushtree(repo, ctx, **args):
+    """:firstpushtree: String. The first tree this changeset was pushed to.
+    """
+    pushes = list(repo.changetracker.pushes_for_changeset(ctx.node()))
+
+    if not pushes:
+        return None
+
+    return pushes[0][0]
+
+
 def extsetup(ui):
     global bz_available
     try:
         extensions.find('bzexport')
         bz_available = True
     except KeyError:
         pass
 
     extensions.wrapcommand(commands.table, 'pull', pullexpand)
 
     revset.symbols['bug'] = revset_bug
     revset.symbols['me'] = revset_me
     revset.symbols['tree'] = revset_tree
+    revset.symbols['firstpushtree'] = revset_firstpushtree
 
     templatekw.keywords['bug'] = template_bug
     templatekw.keywords['bugs'] = template_bugs
     templatekw.keywords['firstrelease'] = template_firstrelease
     templatekw.keywords['firstbeta'] = template_firstbeta
     templatekw.keywords['firstaurora'] = template_firstaurora
     templatekw.keywords['firstnightly'] = template_firstnightly
     templatekw.keywords['auroradate'] = template_auroradate
     templatekw.keywords['nightlydate'] = template_nightlydate
+    templatekw.keywords['firstpushuser'] = template_firstpushuser
+    templatekw.keywords['firstpushtree'] = template_firstpushtree
 
 
 def reposetup(ui, repo):
     """Custom repository implementation.
 
     Our custom repository class tracks remote tree references so users can
     reference specific revisions on remotes.
     """