Bug 1052201 - Migrate hghooks repository into version-control-tools; a=laura default tip
authorGregory Szorc <gps@mozilla.com>
Tue, 12 Aug 2014 08:18:54 -0700
changeset 204 62eddffd848dc8617804412e1de0832b3d49e2e7
parent 203 52f75a0ae929782bb88c796aa299eafe0c139e1f
push id132
push usergszorc@mozilla.com
push dateTue, 12 Aug 2014 15:21:54 +0000
reviewerslaura
bugs1052201
Bug 1052201 - Migrate hghooks repository into version-control-tools; a=laura Content from the repo now lives under the hghooks/ directory of https://hg.mozilla.org/hgcustom/version-control-tools/. The content of this repository has been wiped and replaced with a README stating that.
.hgignore
COPYING
README
convert-pushlog-db.py
example-hgrc
hg_require_single_head
mozhghooks/__init__.py
mozhghooks/commit-message.py
mozhghooks/lockfiles.py
mozhghooks/mirror-example.yaml
mozhghooks/mirror-pull
mozhghooks/mirror_daemon.py
mozhghooks/prevent_broken_csets.py
mozhghooks/prevent_case_only_renames.py
mozhghooks/prevent_unlabelled_australis_changes.py
mozhghooks/prevent_uuid_changes.py
mozhghooks/prevent_webidl_changes.py
mozhghooks/push_printurls.py
mozhghooks/push_repo.py
mozhghooks/pushlog.py
mozhghooks/signal-mirrors.py
mozhghooks/single_head_per_branch.py
mozhghooks/treeclosure.py
mozhghooks/treeclosure_comm_central.py
mozhghooks/try_mandatory.py
mozhghooks/whitelist_qa.py
mozhghooks/whitelist_releng.py
runtests.py
setup.py
tamarin-hook.py
test-convert.sh
deleted file mode 100644
--- a/.hgignore
+++ /dev/null
@@ -1,5 +0,0 @@
-syntax: glob
-
-*~
-*.pyc
-*.pyo
deleted file mode 100644
--- a/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,11 @@
+THIS REPOSITORY AND ITS FULL HISTORY HAS BEEN MIGRATED.
+
+The new location is:
+
+https://hg.mozilla.org/hgcustom/version-control-tools/
+
+You can find the content of this repository under the hghooks/
+directory in that repository. The initial commit to this
+repository (e01e14e32151) is changeset e11fee681380 in
+that repository. The final commit (the parent of this commit)
+(52f75a0ae929) is changeset 1f927bcba52c.
deleted file mode 100644
--- a/convert-pushlog-db.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# Copyright (C) 2010 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-# This script imports data from the older flat-file pushlog format,
-# and the newer sqlite pushlog format into a newer sqlite schema.
-#
-# Unfortunately, when changing between the older format and the db,
-# the semantics changed somewhat. The older format used to record the
-# *HEAD* revision as of a push, but the db records the *first* changeset
-# in a group of pushed changes. To make life simpler, the new schema
-# will record all changesets for a push, but we need to migrate the old data
-# over.
-# To do so, we grab all logged pushes from the old log and the db,
-# and then for each logged push, if it is in the old log, then it's a head,
-# so store all changes since the previous push with this push. Otherwise,
-# it's a 'first changeset', so store all changes up until the next push
-# with this push. At the end we'll have one entry in the new pushlog
-# table for every push, and one entry per-changeset in the changesets
-# table, mapped back to the pushlog table.
-
-try:
-    import sqlite3 as sqlite
-except ImportError:
-    from pysqlite2 import dbapi2 as sqlite
-
-import sys
-import os.path
-import re
-from datetime import datetime
-import time
-from calendar import timegm
-from rfc822 import parsedate_tz, mktime_tz
-from mercurial import ui, hg
-from mercurial.node import hex
-
-reader = re.compile(r'^"([a-f0-9]{40})"\t"([^\t]*)"\t"([^\t]*)"$')
-def readlog(logfile):
-    """Read a pushlog and yield (node, user, date) for each line. Returns
-    all the entries in chronological order. |date| is a timestamp."""
-    try:
-        fd = open(logfile)
-    except IOError:
-        return []
-    entries = []
-    for line in fd:
-        (node, user, date) = reader.match(line).group(1, 2, 3)
-        entries.append((node, user, mktime_tz(parsedate_tz(date))))
-    fd.close()
-    return entries
-
-def readpushdb(pushdb):
-    """Read a pushlog db and yield (node, user, date) for each line. Returns
-    all the entries in chronological order. |date| is a timestamp."""
-    try:
-        conn = sqlite.connect(pushdb)
-        entries = []
-        res = conn.execute("SELECT node, user, date FROM pushlog ORDER BY date ASC")
-        for (node, user, date) in res:
-            entries.append((node, user, timegm(time.strptime(date, "%Y-%m-%dT%H:%M:%SZ"))))
-        return entries
-    except:
-        return []
-
-def nodeindb(pushdb, node):
-    return pushdb.execute("SELECT COUNT(*) from changesets WHERE node = ?", (node,)) == 1
-
-if len(sys.argv) != 2:
-    print >>sys.stderr, "Must specify a repository as the only parameter (/path/to/repo/)"
-    sys.exit(1)
-
-### Main entrypoint
-
-repo_path = os.path.abspath(sys.argv[1])
-if not os.path.exists(repo_path):
-    print >>sys.stderr, "Must specify a repository as the only parameter (/path/to/repo/)"
-    sys.exit(1)
-
-try:
-    repo = hg.repository(ui.ui(), repo_path)
-except:
-    print >>sys.stderr, "Must specify a repository as the only parameter (/path/to/repo/)"
-    sys.exit(1)
-
-# we need to read both the old text pushlog
-pushlog = os.path.join(repo_path, ".hg", "pushlog")
-# ... and the newer pushlog db
-oldpushdb = pushlog + ".db"
-# and we're going to migrate them both to a new schema
-pushdb = pushlog + "2.db"
-
-# Open or create our new db
-conn = sqlite.connect(pushdb)
-conn.execute("CREATE TABLE IF NOT EXISTS changesets (pushid INTEGER, rev INTEGER, node text)")
-conn.execute("CREATE TABLE IF NOT EXISTS pushlog (id INTEGER PRIMARY KEY AUTOINCREMENT, user TEXT, date INTEGER)")
-conn.execute("CREATE UNIQUE INDEX IF NOT EXISTS changeset_node ON changesets (node)")
-conn.execute("CREATE UNIQUE INDEX IF NOT EXISTS changeset_rev ON changesets (rev)")
-conn.execute("CREATE INDEX IF NOT EXISTS pushlog_date ON pushlog (date)")
-conn.execute("CREATE INDEX IF NOT EXISTS pushlog_user ON pushlog (user)")
-
-# Read all entries from both pushlogs
-flatlogentries = readlog(pushlog)
-flatnodes = dict()
-# dict for easy lookup of nodes
-for (node, user, date) in flatlogentries:
-    flatnodes[node] = 1
-logentries = readpushdb(oldpushdb)
-if len(logentries) == 0:
-    # just in case someone is importing from an old flatfile log
-    logentries = flatlogentries
-
-# sort by revision #, just in case we have two pushes with the same date
-logentries = [(node, repo.changectx(node), user, date) for (node,user,date) in logentries]
-logentries.sort(lambda a,b: cmp(a[1].rev(),b[1].rev()))
-
-# start at the beginning
-lastrev = -1
-next = 0
-for (node, ctx, user, date) in logentries:
-    next += 1
-    if nodeindb(conn, node):
-        # already in the database, move along
-        lastrev = ctx.rev()
-        continue
-    res = conn.execute("INSERT INTO pushlog (user, date) VALUES(?,?)",
-                       (user, date))
-    pushid = res.lastrowid
-    # insert this change first
-    conn.execute("INSERT INTO changesets (pushid,rev,node) VALUES(?,?,?)",
-                 (pushid, ctx.rev(), node))
-    if node in flatnodes:
-        # this was a HEAD revision, see if any other changes were pushed
-        # along with it
-        if lastrev != ctx.rev() - 1:
-            for i in range(lastrev+1, ctx.rev()):
-                c = repo.changectx(i)
-                conn.execute("INSERT INTO changesets (pushid,rev,node) VALUES(?,?,?)",
-                 (pushid, c.rev(), hex(c.node())))
-        lastrev = ctx.rev()
-    else:
-        # this was the first change in a set of changes pushed, see
-        # if any other changes were pushed along with it
-        if next < len(logentries):
-            nextctx = repo.changectx(logentries[next][0])
-            if ctx.rev() + 1 != nextctx.rev():
-                for i in range(ctx.rev()+1, nextctx.rev()):
-                    c = repo.changectx(i)
-                    conn.execute("INSERT INTO changesets (pushid,rev,node) VALUES(?,?,?)",
-                                 (pushid, c.rev(), hex(c.node())))
-                    lastrev = c.rev()
-        else: # end of the list, see if we're missing any changes to tip
-            if not 'tip' in ctx.tags():
-                tip =  repo.changectx('tip')
-                # we want everything up to and including tip
-                for i in range(ctx.rev()+1, tip.rev()+1):
-                    c = repo.changectx(i)
-                    conn.execute("INSERT INTO changesets (pushid,rev,node) VALUES(?,?,?)",
-                                 (pushid, c.rev(), hex(c.node())))
-                    lastrev = c.rev()
-
-conn.commit()
deleted file mode 100644
--- a/example-hgrc
+++ /dev/null
@@ -1,7 +0,0 @@
-# hooks are run in the order in which they appear:
-# any hooks which can veto an action (require-singlehead) should be run before
-# hooks which make permanent logs (record-changeset-info)
-
-[hooks]
-pretxnchangegroup.singlehead = python:mozhghooks.single_head_per_branch.hook
-pretxnchangegroup.linearhistory = python:mozhghooks.pushlog.log
deleted file mode 100755
--- a/hg_require_single_head
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-
-if test $(hg heads -t --template 'Test_Head\n' | grep -c "^Test_Head") != "1"; then
-    printf "You may not push multiple heads to this repository.\n" 1>&2;
-    exit 1;
-fi
deleted file mode 100644
deleted file mode 100644
--- a/mozhghooks/commit-message.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2011 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-import re
-from mercurial.node import hex
-
-goodMessage = [re.compile(x, re.I) for x in [
-    r'bug\s+\#?[0-9]+',
-    r'b=[0-9]+',
-    r'no bug',
-
-    r'^(back(ing|ed)?\s+out|backout).*(\s+|\:)[0-9a-f]{12}',
-    r'^(revert(ed|ing)?).*(\s+|\:)[0-9a-f]{12}',
-    r'^add(ed|ing)? tag'
-]]
-
-def isGoodMessage(c):
-    def message(fmt):
-        print "\n\n************************** ERROR ****************************"
-        print fmt.format(rev = hex(c.node())[:12])
-        print c.user()
-        print c.description()
-        print "*************************************************************\n\n"
-
-    desc = c.description()
-    if c.user() in ["ffxbld", "seabld", "tbirdbld", "cltbld",
-                    "Gaia Pushbot <release+gaiajson@mozilla.com>",
-                    "B2G Bumper Bot <release+b2gbumper@mozilla.com>"]:
-        return True
-
-    if "try: " in desc:
-        message("Rev {rev} uses try syntax. (Did you mean to push to Try instead?)")
-        return False
-
-    for r in goodMessage:
-        if r.search(desc):
-            return True
-
-    dlower = desc.lower()
-    if dlower.startswith("merge") or dlower.startswith("merging") or dlower.startswith("automated merge"):
-        if len(c.parents()) == 2:
-            return True
-        else:
-            message("Rev {rev} claims to be a merge, but it has only one parent.")
-            return False
-
-    if dlower.startswith("back") or dlower.startswith("revert"):
-        # Purposely ambiguous: it's ok to say "backed out rev N" or "reverted to rev N-1"
-        message("Backout rev {rev} needs a bug number or a rev id.")
-    else:
-        message("Rev {rev} needs a bug number.")
-
-    return False
-
-def hook(ui, repo, node, hooktype, **kwargs):
-    # All changesets from node to "tip" inclusive are part of this push.
-    rev = repo.changectx(node).rev()
-    tip = repo.changectx("tip").rev()
-    rejecting = False
-
-    for i in reversed(xrange(rev, tip + 1)):
-        c = repo.changectx(i)
-
-        if "IGNORE BAD COMMIT MESSAGES" in c.description():
-            # Ignore commit messages for all earlier revs in this push.
-            break
-
-        if not isGoodMessage(c):
-            # Keep looping so the pusher sees all commits they need to fix.
-            rejecting = True
-
-    if not rejecting:
-      return 0
-
-    # We want to allow using this hook locally
-    if hooktype == "pretxnchangegroup":
-        return 1
-
-    print "This changeset would have been rejected!"
-    return 0 # to fail not warn change to 1
deleted file mode 100644
--- a/mozhghooks/lockfiles.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2011 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-from os import open, close, read, unlink, O_CREAT, O_EXCL
-from time import sleep
-
-def getlock(fname, verbose=False):
-    maxtries=3
-    lockf="%s.lck" % fname
-    fd = False
-    for i in range(0,maxtries):
-        try:
-            fd = open(lockf, O_CREAT|O_EXCL)
-            if verbose:
-                print "Locked %s" % fname
-            return fd
-        except OSError:
-            tries=maxtries-i
-            if verbose:
-                print "Could not lock %s" % fname
-                print "  Will try %i more times" % tries
-            sleep(1)
-    return fd
-
-def unlock(fname, fd, verbose=False):
-    if verbose:
-        print "Unlocking %s" % fname
-    lockf = "%s.lck" % fname
-    close(fd)
-    unlink(lockf)
-
deleted file mode 100644
--- a/mozhghooks/mirror-example.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-# Daemon configuration
-daemon:
-  ssh-id: /etc/mercurial/ssh/id_rsa
-  watch-dir: /dev/shm/hg_pushes
-  maxchildren: 3
-
-# A wildcard setting, for hosts that should get all repo changes.
-# XXX Not currently implemented.
-all:
-  mirrors:
-    - hg-backups.mozilla.org
-
-# For each repository, a list of mirrors.  Repo is given relative
-# to the hgweb url root.
-/mozilla-central:
-  mirrors:
-    - mirror1.build.scl1.mozilla.org
-    - mirror2.build.scl1.mozilla.org
deleted file mode 100755
--- a/mozhghooks/mirror-pull
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/bin/sh
-
-die() {
-    echo "$1" 1>&2
-    exit ${2:-1}
-}
-
-usage() {
-    echo "USAGE"
-    echo " $0 [-r source_repo_root] [-t target_directory] <repository>"
-    echo
-}
-
-TEMP=`getopt --options hr:t:l: --long help,root:,target:lock-retries: \
-    -n 'mirror-pull' -- "$@"`
-if [ $? != 0 ]; then
-    die "getopt barfed"
-fi
-
-eval set -- "$TEMP"
-
-# defaults:
-REPO_ROOT=http://hg.mozilla.org
-REPO_TARGET=/repo/hg/mozilla
-LOCK_RETRIES=15 # every 8 seconds for 2 minutes
-
-while true; do
-    case "$1" in 
-        -r|--root)
-            REPO_ROOT="$2" ; shift 2
-            ;;
-        -t|--target)
-            REPO_TARGET="$2" ; shift 2
-            ;;
-        -l|--lock-retries)
-            LOCK_RETRIES="$2" ; shift 2
-            ;;
-        -h|--help)
-            usage
-            exit 0
-            ;;
-        --)
-            shift ; break
-            ;;
-        *)
-            die "I don't know what happened."
-            ;;
-    esac
-done
-
-if [ -n "$SSH_ORIGINAL_COMMAND" ]; then
-    # We're running under ssh; the repository is given in the third field
-    repo=`echo $SSH_ORIGINAL_COMMAND | cut -d ' ' -f 3`
-else
-    repo="$1"
-fi
-
-repo=`echo "$repo" | sed 's#[^-\._/[:alnum:]]##g'`
-test -z "$repo" && die "need a repo to clone, relative to /repo/hg/mozilla" 
-
-GLOBAL_HG_OPTS="--config hooks.pretxnchangegroup.z_linearhistory= --config hooks.pretxnchangegroup.z_loghistory="
-
-name=`echo $repo | sed 's#^/*##'`
-src=${REPO_ROOT}/$name
-
-cd $REPO_TARGET || die "$REPO_TARGET does not exist, cannot create repositories there"
-
-exit_code=0
-if [ -d "$name" ]; then
-    echo "$name already exists, pulling"
-    lockf="${PWD}/${name}.lck"
-    lockfile -r $LOCK_RETRIES $lockf || die "Could not lock destination"
-    cd $name
-    hg pull $GLOBAL_HG_OPTS 
-    exit_code=$?
-    rm -f $lockf
-elif [ \! -e $name ]; then
-    mkdir -p `dirname $name` 
-    echo "$name does not yet exist, cloning"
-    lockf="${PWD}/${name}.lck" || die "Could not lock destination"
-    lockfile -r $LOCK_RETRIES $lockf
-    hg clone $GLOBAL_HG_OPTS -U -v "$src" $name
-    exit_code=$?
-    rm -f $lockf
-else
-    die "WTF is $REPO_TARGET/$name"
-fi
-
-exit $exit_code
-
-# Local variables:
-# mode: shell-script
-# tab-width: 4
-# indent-tabs-mode: nil
-# end:
deleted file mode 100755
--- a/mozhghooks/mirror_daemon.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2011 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-import random
-import os
-from lockfiles import getlock, unlock
-from subprocess import Popen, PIPE, STDOUT
-from time import sleep
-import urllib
-import shlex
-import yaml
-import signal
-
-random.seed()
-# Set by signal handlers:
-exit_requested = False
-
-class MirrorJob:
-    def __init__(self, host, path, config, fh, verbose=False):
-        self.host = host
-        self.path = path
-        self.config = config
-        self.verbose = verbose
-        self.child = None
-        self.command = self.make_command()
-
-    # Given a host and path to clone, return the command used to trigger a
-    # pull.
-    def make_command(self):
-        ssh_id = get_config_key(self.config, ['daemon', 'ssh-id'])
-        if ssh_id:
-            id_str = "-i%s" % ssh_id
-        else:
-            id_str = ""
-        return "/usr/bin/ssh -n %s %s hg pull %s" % (id_str, self.host, self.path)
-
-    # Spawn a child process for the given command
-    def spawn_child(self):
-        self.child = Popen(shlex.split(self.command), stdout=PIPE, stderr=STDOUT)
-        if self.verbose:
-            print "Spawned [%s] as pid %i" % (self.command, self.child.pid)
-        
-# Spawn subprocesses for each of the given commands, up to
-# max_children.  Returns two lists of MirrorJob objects, one
-# containing the running jobs, and one containing jobs that
-# were not spawned for some reason.
-def spawn_children(commands, running_jobs, max_children, verbose=False):
-    procs = running_jobs
-    skipped_jobs = []
-    # while len(procs) < max_children and len(commands) > 0:
-    for i in range(0, len(commands)):
-        if(len(procs) >= max_children or
-           check_dup_jobs(commands[i], running_jobs)):
-               skipped_jobs.append(commands[i])
-        else:
-            commands[i].spawn_child()
-            procs.append(commands[i])
-    if verbose:
-        print "Spawned %i processes, %i pending" % ( len(procs), len(skipped_jobs) )
-    return (procs, skipped_jobs)
-
-# Check to see if a running job already exists for the
-# given host/repo pair.  Returns boolean
-def check_dup_jobs(job, running_jobs):
-    for cur in running_jobs:
-        if(job.host == cur.host and
-           job.path == cur.path):
-            return True
-    return False
-
-# check each child process, gather any output, 
-def reap_children(jobs, verbose=False):
-    if verbose:
-        print "in reap_children, nchildren = %i" % len(jobs)
-    for job in jobs:
-        output = None
-        rcode = job.child.poll()
-        if(rcode != None):
-            output = job.child.communicate()
-            if(rcode == 0):
-                print "Successfully pushed %s to %s" % (job.path, job.host)
-            else:
-                print "ERROR: Push of %s to %s returned %i" % (job.path, job.host, rcode)
-            if verbose:
-                if output:
-                    print "Output: %s" % output[0]
-            jobs.remove(job)
-    return jobs
-
-# Different repositories might get mirrored to different hosts.  For a
-# given repository, return a list of hosts that should receive push
-# notifications.
-def get_hosts_for_repo(repo, config):
-    hosts = get_config_key(config, [repo, 'mirrors'])
-    if hosts:
-        return hosts
-    else:
-        return []
-
-# Look for repositories that have been updated. Return a list of
-# commands to run to notify the appropriate mirrors that they should
-# update.
-def get_more_commands(directory, config, verbose=False):
-    cmnds = []
-    if verbose:
-        print "Looking for files in %s" % directory
-    dirh = os.listdir(directory)
-    for f in dirh:
-        fullpath = "%s/%s" % (directory, f)
-        lck = getlock(fullpath, verbose)
-        if lck:
-            fh = file(fullpath, 'r')
-            os.unlink(fullpath)
-            unlock(fullpath, lck, verbose)
-            for host in get_hosts_for_repo(urllib.unquote(f), config):
-                cmnds.append(MirrorJob(host, 
-                                       urllib.unquote(f), 
-                                       config,
-                                       fh))
-                if verbose:
-                    print "Appended a command to the queue. ",
-                    print "qlen: %i" % len(cmnds)
-            fh.close()
-        else:
-            print "Couldn't lock %s" % fullpath
-    return cmnds
-
-# Read the config file. Returns a dictionary object, which may be empty
-def read_config(configfile):
-    try:
-        f = file(configfile)
-    except IOError, e:
-        print "WARNING: mirror config %s: %s" % (configfile, e)
-        return {}
-    y = yaml.load(f)
-    f.close()
-    if y == None:
-        y = {}
-    return y
-
-# get the config value specified by the given path array.
-# Returns the requested value or None if it's not present.
-def get_config_key(config, path):
-    try:
-        if len(path) == 0:
-            return config
-        current = path[0]
-        del path[0]
-        return get_config_key(config[current], path)
-    except KeyError:
-        return None
-
-def main():
-    global exit_requested
-    running_jobs = []
-    pending_jobs = []
-    configfile = "/etc/mercurial/repo-mirrors.yaml"
-    cfg = read_config(configfile)
-
-    # Read some global values from the config file, filling in
-    # some sane-ish defaults for missing values.
-    verbose = get_config_key(cfg, ['daemon', 'verbose'])
-    dir = get_config_key(cfg, ['daemon', 'watch-dir'])
-    if not dir:
-        dir = "/dev/shm/hg_pushes"
-    maxchildren = get_config_key(cfg, ['daemon', 'maxchildren'])
-    if not maxchildren:
-        maxchildren = 3
-
-    def sighandler(signum, frame):
-        print "Caught signal %i" % signum
-        global exit_requested
-        exit_requested = True
-        if(len(running_jobs) > 0 or len(pending_jobs) > 0):
-            print "WARNING: There are %i running jobs and %i queued jobs" % (len(running_jobs), 
-                                                                             len(pending_jobs))
-            print "WARNING: To ensure a clean exit, will terminate after the queue is emptied"
-
-    signal.signal(signal.SIGTERM, sighandler)
-
-    while True:
-        if not exit_requested:
-            pending_jobs = pending_jobs + get_more_commands(dir, cfg, verbose)
-        running_jobs = reap_children(running_jobs, verbose)
-        (running_jobs, pending_jobs) = spawn_children(pending_jobs, running_jobs,
-                                                      maxchildren - len(running_jobs), 
-                                                      verbose)
-        if(exit_requested and
-           len(running_jobs) == 0 and 
-           len(pending_jobs) == 0):
-            break
-        sleep(1)
-    print "Exiting..."
-
-if __name__ == "__main__":
-    main()
-
deleted file mode 100755
--- a/mozhghooks/prevent_broken_csets.py
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2013 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-'''This hook detects csets which hit hg bug 3833 [1] and break our hg blame.
-
-An example of one such bad commit is dad25c17ccc7 in mozilla-central.
-
-This hook should be used as a pre-commit hook on all trees except try.
-
-[1] http://bz.selenic.com/show_bug.cgi?id=3833.
-'''
-
-from __future__ import print_function
-import os
-import sys
-import traceback
-import textwrap
-from mercurial import ui, scmutil, cmdutil
-from mercurial.node import hex, short, nullid
-
-magicwords = 'IGNORE BROKEN CHANGESETS'
-
-def dedent_and_fill(s):
-    r'''This is like textwrap.fill(textwrap.dedent(s)) except it respects
-    paragraphs in the text.  That is, " foo\n\n bar" is rendered as
-    "foo\n\nbar", instead of "foo bar".
-
-    This function also adds a blank line to the beginning of the input.
-
-    '''
-    s = textwrap.dedent(s)
-
-    paragraphs = ['']
-    current_paragraph = []
-    for line in s.split('\n'):
-        if line.strip():
-            current_paragraph.append(line)
-        elif current_paragraph:
-            paragraphs.append(' '.join(current_paragraph))
-            paragraphs.append('')
-            current_paragraph = []
-    if current_paragraph:
-        paragraphs.append(' '.join(current_paragraph))
-
-    return '\n'.join([textwrap.fill(p) for p in paragraphs])
-
-class BrokenCsetException(Exception):
-    def __init__(self, cset):
-        self.cset = cset
-
-    def __str__(self):
-        return 'Broken changeset: %s' % str(self.cset)
-
-def hook(ui, repo, hooktype, node, **kwargs):
-    # We don't want to apply this hook to try or user repos.  (repo.root seems
-    # to be a normalized, absolute path, but there's no harm in being sure.)
-    repo_path = os.path.normpath(os.path.abspath(repo.root))
-    if repo_path == '/repo/hg/mozilla/try' or \
-       repo_path.startswith('/repo/hg/mozilla/users'):
-        return 0
-
-    if repo.changectx('tip').description().find(magicwords) != -1:
-        print(dedent_and_fill('''\
-            Not checking this push for broken changesets because the tip cset
-            contains %s.  I hope you mean it!
-            ''' % magicwords))
-        return 0
-
-    try:
-        check_for_broken_csets(repo, node)
-    except BrokenCsetException as e:
-        print(dedent_and_fill('''\
-            Broken changeset detected: %s!
-
-            Our pre-commit hook detected a broken changeset in your push: %s.
-            This changeset was likely produced by a version of hg older than
-            2.5.  We're rejecting your push because this cset may break hg
-            blame [1].
-
-            Please upgrade to hg 2.5.1 or newer (2.5 contains known bugs),
-            qimport your changes, then qpop, qpush, and qfinish them.  You
-            might do:
-
-              $ hg qimport --rev 'outgoing()'
-              $ hg qpop -a && hg qpush -a && hg qfinish -a
-
-            If this doesn't solve the problem, or if you're sure that these
-            commits were generated using hg 2.5 or newer, please ask someone in
-            #it, or file a bug.
-
-            You can work around this hook by putting "%s" in your topmost
-            changeset, but please don't use this lightly.
-
-            [1] https://bugzilla.mozilla.org/show_bug.cgi?id=843081
-            ''' %
-            (e.cset, e.cset, magicwords)))
-
-        # Reject the push.
-        return 1
-    except Exception:
-        print(dedent_and_fill('''\
-            WARNING: The prevent_broken_csets pre-commit hook encountered an
-            unexpected error.  We're going to allow your push to go through,
-            but please ping someone in #it or file a bug in
-
-              mozilla.org :: Server Operations: Developer Services
-
-            so that the right people are informed of this issue.  Thanks!
-            '''))
-        traceback.print_exc(file=sys.stdout)
-
-    # Accept the push
-    return 0
-
-def check_for_broken_csets(repo, push_root):
-    '''Check for broken changesets.  If we find one, we raise a
-    BrokenCsetException.  Otherwise we return without error.
-
-    '''
-    push_root_node = repo[push_root]
-
-    # Gather all the leaf nodes in this push.  There should be at least one; I
-    # don't know what it means to push without any leaves!
-    leaves = []
-    for change_id in xrange(push_root_node.rev(), len(repo)):
-        n = repo[change_id]
-        if not n.children():
-            leaves.append(n)
-
-    if not leaves:
-        print(dedent_and_fill('''\
-            WARNING: No leaf nodes in this push?  This is probably a bug
-            in the commit hook.  Please ask someone in #it about this, or
-            file a bug in
-
-              mozilla.org :: Server Operations: Developer Services.
-
-            In the meantime, we won't reject your push.'''))
-        return
-
-    # For each leaf, gather the set of files modified between the leaf and the
-    # parent(s) of the base commit.
-    modified_files = set()
-    for leaf_node in leaves:
-        for p in push_root_node.parents():
-            modified_files.update(repo.status(node1=p, node2=leaf_node)[0])
-
-    # Check each of these files' debugindex entries.
-    for filename in modified_files:
-        check_debugindex(repo, filename, push_root_node.rev())
-
-def check_debugindex(repo, filename, min_rev):
-    '''Check hg's debugindex for filename for bad csets.  A cset is bad if both parents
-    are null and if it comes from this push (i.e., linkrev >= min_rev).
-
-    If we find a bad changeset, we throw a BrokenCsetException.
-
-    '''
-    # I don't entirely understand what this does, but it's similar to the
-    # debugindex command in hg's commands.py.  See also
-    # http://bz.selenic.com/show_bug.cgi?id=3833#c20
-
-    r = cmdutil.openrevlog(repo, 'debugindex', filename,
-                           {'changelog': False, 'manifest': False})
-    for i in r:
-        node = r.node(i)
-        linkrev = repo[r.linkrev(i)]
-        if linkrev.rev() < min_rev:
-            continue
-        try:
-            parents = r.parents(node)
-        except Exception:
-            parents = (nullid, nullid)
-
-        # If this file has no parents, check whether the relevant rev modified
-        # the file (as opposed to, for example, adding it).  If the rev did
-        # modify the file, then this is a bad changeset.
-        if parents == (nullid, nullid) and \
-           filename in repo.status(node1=linkrev.p1(), node2=linkrev)[0]:
-                raise BrokenCsetException(linkrev)
deleted file mode 100644
--- a/mozhghooks/prevent_case_only_renames.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2011 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-"""
-This hook is designed to prevent renames that only change the case of a file.
-"""
-from mercurial.node import hex, short
-
-def hook(ui, repo, node, hooktype, **kwargs):
-    # All changesets from node to "tip" inclusive are part of this push.
-    rev = repo.changectx(node).rev()
-    tip = repo.changectx("tip").rev()
-    rejecting = False
-
-    for i in range(rev, tip + 1):
-        ctx = repo.changectx(i)
-        for f in ctx:
-            fctx = ctx.filectx(f)
-            r = fctx.renamed()
-            if not r:
-                continue
-            if f.lower() == r[0].lower():
-                rejecting = True
-                print "\n\n************************** ERROR ****************************"
-                print "File rename in changeset %s only changes file case! (%s to %s)" % (short(hex(ctx.node())), r[0], f)
-                print "*************************************************************\n\n"
-    return 1 if rejecting else 0
deleted file mode 100644
--- a/mozhghooks/prevent_unlabelled_australis_changes.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2012 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-"""
-This hook prevents changes from being made to Australis-related files,
-unless the commit message contains "australis" or an override string.
-"""
-from mercurial.node import short
-
-
-def printError(c):
-    print "\n\n************************** ERROR ****************************"
-    print "Changeset %s appears to make australis changes, but does" % short(c.node())
-    print "not contain \"australis\" in the commit message! (See bug 943486)"
-    print " -> \"%s\"" % c.description()
-    print "*************************************************************"
-
-
-def hook(ui, repo, node, hooktype, **kwargs):
-    changesets = list(repo.changelog.revs(repo[node].rev()))
-    rejecting = False
-
-    # All changesets in this push, starting at tip (so the override works).
-    # Note: Unless the override was used, we do not break the outer loop, so
-    # that the pusher can see all of the commits that need fixing in one go.
-    for i in reversed(changesets):
-        c = repo.changectx(i)
-
-        desc = c.description()
-
-        if "OVERRIDE HOOK" in desc:
-            # Skip all earlier commits in this push.
-            break
-
-        if "australis" in desc.lower():
-            # This commit is labelled correctly, proceed to the next.
-            continue
-
-        if len(c.parents()) > 1:
-            # Skip merge changesets
-            continue
-
-        for file in c.files():
-            if ((file.startswith("browser/themes/") and "devtools" not in file) or
-                    file.startswith("browser/components/customizableui/")):
-                # Australis-related files found.
-                rejecting = True
-                printError(c)
-                break
-
-    return 1 if rejecting else 0
deleted file mode 100755
--- a/mozhghooks/prevent_uuid_changes.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2012 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-"""
-This hook is to prevent changes to IID or UUID in pushes to trees where such changes could cause critical issues (eg: beta, release).
-"""
-
-import re
-
-def hook(ui, repo, hooktype, node, **kwargs):
-    error = ""
-    bc = False
-    # Loop through each changeset being added to the repository
-    for change_id in xrange(repo[node].rev(), len(repo)):
-        # Loop through each file for the current changeset
-        for file in repo[change_id].files():
-            # Only Check IDL Files
-            if file.endswith('.idl'):
-                bc = True
-                if not re.search('ba\S*=', repo.changectx('tip').description().lower()):
-                        error += "IDL file %s altered in this changeset" % file
-    # Check if an error occured in any of the files that were changed
-    if error != "":
-        print "\n\n************************** ERROR ****************************"
-        ui.warn("\n\r*** " + error + "***\n\r")
-        print "\n\rChanges to IDL files in this repo require you to provide binary change approval in your top comment in the form of ba=... (or, more accurately, ba\\S*=...)\n\rThis is to ensure that UUID changes (or method changes missing corresponding UUID change) are caught early, before release.\n\r"
-        print "*************************************************************\n\n"
-        # Reject the changesets
-        return 1
-    else:
-        if bc:
-            print "You've signaled approval for the binary change(s) in your push, thanks for the extra caution."
-    # Accept the changesets
-    return 0
deleted file mode 100755
--- a/mozhghooks/prevent_webidl_changes.py
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2012 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-"""
-This hook is to prevent changes to .webidl files in pushes without proper DOM peer review.
-"""
-
-import re
-from mercurial.node import short
-from mercurial import util
-
-backoutMessage = [re.compile(x) for x in [
-    r'^(back(ing|ed)?\s+out|backout)',
-    r'^(revert(ed|ing)?)'
-]]
-
-def isBackout(message):
-    for r in backoutMessage:
-        if r.search(message):
-            return True
-    return False
-
-def hook(ui, repo, hooktype, node, **kwargs):
-    DOM_peers = [
-        'jst',              # Johnny Stenback
-        'peterv',           # Peter Van der Beken
-        'bz', 'bzbarsky',   # Boris Zbarsky
-        'sicking', 'jonas', # Jonas Sicking
-        'smaug',            # Olli Pettay
-        'bent',             # Ben Turner
-        'mounir',           # Mounir Lamouri
-        'khuey',            # Kyle Huey
-        'jlebar',           # Justin Lebar
-        'hsivonen',         # Henri Sivonen
-        'mrbkap',           # Blake Kaplan
-        'bholley',          # Bobby Holley
-    ]
-    DOM_authors = [
-        'jst@mozilla.com',         # Johnny Stenback
-        'peterv@propagandism.org', # Peter Van der Beken
-        'bzbarsky@mit.edu',        # Boris Zbarsky
-        'jonas@sicking.cc',        # Jonas Sicking
-        'olli.pettay@helsinki.fi', # Olli Pettay
-        'bent.mozilla@gmail.com',  # Ben Turner
-        'mounir@lamouri.fr',       # Mounir Lamouri
-        'khuey@kylehuey.com',      # Kyle Huey
-        'justin.lebar@gmail.com',  # Justin Lebar
-        'hsivonen@hsivonen.fi',    # Henri Sivonen
-        'mrbkap@gmail.com',        # Blake Kaplan
-    ]
-    error = ""
-    webidlReviewed = False
-    changesets = list(repo.changelog.revs(repo[node].rev()))
-    if 'a=release' in repo.changectx(changesets[-1]).description().lower():
-        # Accept the entire push for code uplifts.
-        return 0
-    # Loop through each changeset being added to the repository
-    for i in reversed(changesets):
-        c = repo.changectx(i)
-
-        if len(c.parents()) > 1:
-            # Skip merge changesets
-            continue
-
-        # Loop through each file for the current changeset
-        for file in c.files():
-            # Only Check WebIDL Files
-            if file.endswith('.webidl'):
-                message = c.description().lower()
-                email = util.email(c.user())
-                def search():
-                  matches = re.findall('\Ws?r\s*=\s*(\w+(?:,\w+)*)', message)
-                  for match in matches:
-                      for reviewer in match.split(','):
-                          if reviewer in DOM_peers:
-                              return True
-                  # We allow DOM peers to commit changes to WebIDL files without any review
-                  # requirements assuming that they have looked at the changes they're committing.
-                  for peer in DOM_authors:
-                      if peer == email:
-                          return True
-                  return False
-                webidlReviewed = search()
-                if not webidlReviewed and not isBackout(message):
-                        error += "WebIDL file %s altered in changeset %s without DOM peer review\n" % (file, short(c.node()))
-    # Check if an error occured in any of the files that were changed
-    if error != "":
-        print "\n\n************************** ERROR ****************************"
-        ui.warn("\n" + error + "\n")
-        print "\n\rChanges to WebIDL files in this repo require review from a DOM peer in the form of r=...\n\rThis is to ensure that we behave responsibly with exposing new Web APIs. We appreciate your understanding..\n\r"
-        print "*************************************************************\n\n"
-        # Reject the changesets
-        return 1
-    else:
-        if webidlReviewed:
-            print "You've received proper review from a DOM peer on your WebIDL change(s) in your push, thanks for paying enough attention."
-    # Accept the changesets
-    return 0
deleted file mode 100644
--- a/mozhghooks/push_printurls.py
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/usr/bin/python
-import os.path
-from mercurial.node import short
-
-hgNameToRevURL = {
-    # Gecko trunk / integration branches
-    'b2g-inbound':      'integration/b2g-inbound/',
-    'build-system':     'projects/build-system',
-    'fx-team':          'integration/fx-team/',
-    'mozilla-central':  'mozilla-central/',
-    'mozilla-inbound':  'integration/mozilla-inbound/',
-    'services-central': 'services/services-central/',
-    # Gecko release branches
-    'mozilla-aurora':  'releases/mozilla-aurora/',
-    'mozilla-beta':    'releases/mozilla-beta/',
-    'mozilla-release': 'releases/mozilla-release/',
-    'mozilla-esr24':   'releases/mozilla-esr24/',
-    'mozilla-esr31':   'releases/mozilla-esr31/',
-    # Gecko B2G branches
-    'mozilla-b2g32_v2_0':      'releases/mozilla-b2g32_v2_0/',
-    'mozilla-b2g30_v1_4':      'releases/mozilla-b2g30_v1_4/',
-    'mozilla-b2g28_v1_3':      'releases/mozilla-b2g28_v1_3/',
-    'mozilla-b2g28_v1_3t':     'releases/mozilla-b2g28_v1_3t/',
-    # Thunderbird branches
-    'comm-central': 'comm-central/',
-    'comm-aurora':  'releases/comm-aurora/',
-    'comm-beta':    'releases/comm-beta/',
-    'comm-release': 'releases/comm-release/',
-    'comm-esr24':   'releases/comm-esr24/',
-    'comm-esr31':   'releases/comm-esr31/',
-    # Try repos
-    'try':              'try/',
-    'try-comm-central': 'try-comm-central/',
-}
-
-# Project branches that are in active use
-hgNameToRevURL.update({
-    'alder':   'projects/alder/',
-    'ash':     'projects/ash/',
-    'birch':   'projects/birch/',
-    'cedar':   'projects/cedar/',
-    'cypress': 'projects/cypress/',
-    'date':    'projects/date/',
-    'elm':     'projects/elm/',
-    'fig':     'projects/fig/',
-    'gum':     'projects/gum/',
-    'holly':   'projects/holly/',
-    'jamun':   'projects/jamun/',
-    'larch':   'projects/larch/',
-    'maple':   'projects/maple/',
-    'oak':     'projects/oak/',
-    'pine':    'projects/pine/',
-})
-
-# QA repos
-hgNameToRevURL.update({
-    'mozmill-tests':        'qa/mozmill-tests/',
-    'testcase-data':        'qa/testcase-data/',
-})
-
-# RelEng repos
-hgNameToRevURL.update({
-    'autoland':             'build/autoland/',
-    'braindump':            'build/braindump/',
-    'buildapi':             'build/buildapi/',
-    'buildbot':             'build/buildbot/',
-    'buildbot-configs':     'build/buildbot-configs/',
-    'buildbotcustom':       'build/buildbotcustom/',
-    'cloud-tools':          'build/cloud-tools/',
-    'compare-locales':      'build/compare-locales/',
-    'fork-hg-git':          'build/fork-hg-git/',
-    'hghooks':              'hgcustom/hghooks/',
-    'mozharness':           'build/mozharness/',
-    'mozpool':              'build/mozpool/',
-    'opsi-package-sources': 'build/opsi-package-sources/',
-    'partner-repacks':      'build/partner-repacks/',
-    'preproduction':        'build/preproduction/',
-    'puppet':               'build/puppet/',
-    'puppet-manifests':     'build/puppet-manifests/',
-    'rpm-sources':          'build/rpm-sources/',
-    'talos':                'build/talos/',
-    'tbpl':                 'webtools/tbpl/',
-    'tools':                'build/tools/',
-    'twisted':              'build/twisted/',
-})
-
-def hook(ui, repo, node, hooktype, **kwargs):
-    repo_name = os.path.basename(repo.root)
-    if repo_name not in hgNameToRevURL:
-        return 0
-
-    # All changesets from node to "tip" inclusive are part of this push.
-    rev = repo.changectx(node).rev()
-    tip = repo.changectx('tip').rev()
-
-    # For try, print out a TBPL url rather than the pushlog
-    if repo_name == 'try':
-        tip_node = short(repo.changectx(tip).node())
-        print 'You can view the progress of your build at the following URL:'
-        print '  https://tbpl.mozilla.org/?tree=Try&rev=%s' % tip_node
-        print 'Alternatively, view them on Treeherder (experimental):'
-        print '  https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=%s' % tip_node
-        return 0
-
-    # For try-comm-central, print out a TBPL url rather than the pushlog
-    if repo_name == 'try-comm-central':
-        tip_node = short(repo.changectx(tip).node())
-        print 'You can view the progress of your build at the following URL:'
-        print '  https://tbpl.mozilla.org/?tree=Thunderbird-Try&rev=%s' % tip_node
-        print 'Alternatively, view them on Treeherder (experimental):'
-        print '  https://treeherder.mozilla.org/ui/#/jobs?repo=thunderbird-try&revision=%s' % tip_node
-        return 0
-
-    num_changes = tip + 1 - rev
-    url = 'https://hg.mozilla.org/' + hgNameToRevURL[repo_name]
-
-    if num_changes <= 10:
-        plural = 's' if num_changes > 1 else ''
-        print 'You can view your change%s at the following URL%s:' % (plural, plural)
-
-        for i in xrange(rev, tip + 1):
-            node = short(repo.changectx(i).node())
-            print '  %srev/%s' % (url, node)
-    else:
-        tip_node = short(repo.changectx(tip).node())
-        print 'You can view the pushlog for your changes at the following URL:'
-        print '  %spushloghtml?changeset=%s' % (url, tip_node)
-
-    return 0
deleted file mode 100644
--- a/mozhghooks/push_repo.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2011 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-import sys
-sys.path.append('/repo/hg/libraries/mozhghoooks')
-
-from optparse import OptionParser
-from mirror_daemon import *
-from time import sleep
-
-configfile = "/etc/mercurial/repo-mirrors.yaml"
-cfg = read_config(configfile)
-
-parser = OptionParser()
-parser.add_option("-r", "--repo", dest="repo", 
-                  help="Repository path, relative to http://hg.m.o", 
-                  metavar="REPO")
-parser.add_option("-H", "--host", dest="tgt_host",
-                  help="username@host to push to", metavar="USER@HOST")
-(options, args) = parser.parse_args()
-
-repo = options.repo
-host = options.tgt_host
-
-if not repo or not host:
-    parser.print_help()
-    sys.exit(1)
-
-# Read some global values from the config file, filling in
-# some sane-ish defaults for missing values.
-verbose = get_config_key(cfg, ['daemon', 'verbose'])
-maxchildren = 1
-
-job = MirrorJob(host, repo, cfg, None, True)
-job.spawn_child()
-
-while True:
-  rcode = job.child.poll()
-  if rcode != None:
-    output = job.child.communicate()
-    print "Job finished with code %i. Output follows:" % rcode
-    print output[0]
-    break
-  else:
-    sleep(1)
deleted file mode 100644
--- a/mozhghooks/pushlog.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2010 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-# This script implements a Mercurial hook to log the date and time when
-# changesets are pushed into a repository, and the user that pushed them.
-#
-# run `python setup.py install` to install the module in the proper place,
-# and then modify the repository's hgrc as per example-hgrc.
-
-from mercurial import demandimport
-
-demandimport.disable()
-try:
-    import sqlite3 as sqlite
-except ImportError:
-    from pysqlite2 import dbapi2 as sqlite
-demandimport.enable()
-
-import time
-import os
-import os.path
-import stat
-from mercurial.node import hex
-
-def createpushdb(conn):
-    conn.execute("CREATE TABLE IF NOT EXISTS changesets (pushid INTEGER, rev INTEGER, node text)")
-    conn.execute("CREATE TABLE IF NOT EXISTS pushlog (id INTEGER PRIMARY KEY AUTOINCREMENT, user TEXT, date INTEGER)")
-    conn.execute("CREATE UNIQUE INDEX IF NOT EXISTS changeset_node ON changesets (node)")
-    conn.execute("CREATE UNIQUE INDEX IF NOT EXISTS changeset_rev ON changesets (rev)")
-    conn.execute("CREATE INDEX IF NOT EXISTS changeset_pushid ON changesets (pushid)")
-    conn.execute("CREATE INDEX IF NOT EXISTS pushlog_date ON pushlog (date)")
-    conn.execute("CREATE INDEX IF NOT EXISTS pushlog_user ON pushlog (user)")
-    conn.commit()
-
-def schemaexists(conn):
-    return 1 == conn.execute("SELECT COUNT(*) FROM SQLITE_MASTER WHERE name='pushlog'").fetchone()[0]
-
-def log(ui, repo, node, **kwargs):
-    pushdb = os.path.join(repo.path, 'pushlog2.db')
-    createdb = False
-    if not os.path.exists(pushdb):
-        createdb = True
-    conn = sqlite.connect(pushdb)
-    if not createdb and not schemaexists(conn):
-        createdb = True
-    if createdb:
-        createpushdb(conn)
-        st = os.stat(pushdb)
-        os.chmod(pushdb, st.st_mode | stat.S_IWGRP)
-    t = int(time.time())
-    retval = 1
-    print "Trying to insert into pushlog."
-    print "Please do not interrupt..."
-    try:
-        res = conn.execute("INSERT INTO pushlog (user, date) values(?,?)",
-                           (os.environ['USER'], t))
-        pushid = res.lastrowid
-        # all changesets from node to 'tip' inclusive are part of this push
-        rev = repo.changectx(node).rev()
-        tip = repo.changectx('tip').rev()
-        for i in range(rev, tip+1):
-            ctx = repo.changectx(i)
-            conn.execute("INSERT INTO changesets (pushid,rev,node) VALUES(?,?,?)",
-                         (pushid, ctx.rev(), hex(ctx.node())))
-        conn.commit()
-        retval = 0
-        print "Inserted into the pushlog db successfully."
-    except sqlite.OperationalError:
-        print "Pushlog database is locked. Please retry your push."
-    conn.close()
-    return retval
deleted file mode 100644
--- a/mozhghooks/signal-mirrors.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (C) 2011 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-import os
-import time
-from mercurial import hg, ui, commands, node
-import re
-import urllib
-from lockfiles import getlock, unlock
-
-repo_toplevel="/repo/hg/mozilla"
-workdir="/dev/shm/hg_pushes"
-
-def hook(ui, repo, **kwargs):
-    if not os.path.isdir(workdir):
-        os.mkdir(workdir)
-        # mode 0777 is unfortunate, but we don't have a more appropriate
-        # group at this time...
-        os.chmod(workdir, 0777)
-    repo_name = os.path.basename(repo.root)
-    url_path = re.sub('^%s' % repo_toplevel, '', repo.root)
-    # Escape '/' characters in url path, so we can store this
-    # info in a filename:
-    escaped_path = urllib.quote(url_path, '')
-    outfile = "%s/%s" % (workdir, escaped_path)
-    lockfd = getlock(outfile)
-    if lockfd:
-        ui.debug("Writing mirror trigger to %s\n" % outfile)
-        outf = file(outfile, "w")
-        if(outf):
-            print >> outf, kwargs['node']
-            outf.close()
-        else:
-            print "Oh no, I couldn't open %s" % outfile
-    else:
-        print "Crap. Couldn't lock %s" % outfile
-    unlock(outfile, lockfd)
deleted file mode 100755
--- a/mozhghooks/single_head_per_branch.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2010 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-def hook(ui, repo, **kwargs):
-    for b in repo.branchtags():
-        if len(repo.branchheads(b)) > 1:
-            print "\n\n************************** ERROR ****************************"
-            print "Two heads detected on branch '%s'" % b
-            print "Only one head per branch is allowed!"
-            print "*************************************************************\n\n"
-            return 1
-    return 0
deleted file mode 100644
--- a/mozhghooks/treeclosure.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2012 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-from urllib2 import urlopen
-import os.path
-import re
-import json
-
-magicwords = "CLOSED TREE"
-
-treestatus_base_url = "https://treestatus.mozilla.org"
-
-def printError(message):
-    print "\n\n************************** ERROR ****************************"
-    print message
-    print "*************************************************************\n\n"
-
-def hook(ui, repo, **kwargs):
-    name = os.path.basename(repo.root)
-    url = "%s/%s?format=json" % (treestatus_base_url, name)
-    try:
-        u = urlopen(url)
-        data = json.load(u)
-        if data['status'] == 'closed':
-            print "Tree %s is CLOSED! (%s) - %s" % (name, url, data['reason'])
-
-            # Block the push unless they know the magic words
-            if repo.changectx('tip').description().find(magicwords) == -1:
-                printError("To push despite the closed tree, include \"%s\" in your push comment" % magicwords)
-                return 1
-
-            print "But you included the magic words.  Hope you had permission!"
-            return 0
-        elif data['status'] == 'approval required':
-            # Block the push unless they have approval or are backing out
-            dlower = repo.changectx('tip').description().lower()
-            if re.search('a\S*=', dlower) or dlower.startswith('back') or dlower.startswith('revert'):
-                return 0
-
-            printError("Pushing to an APPROVAL REQUIRED tree requires your top changeset comment to include: a=... (or, more accurately, a\\S*=...)")
-            return 1
-
-    except (ValueError, IOError), (err):
-        # fail closed if treestatus is down, unless the magic words have been used
-        printError("Error accessing %s :\n"
-                   "%s\n"
-                   "Unable to check if the tree is open - treating as if CLOSED.\n"
-                   "To push regardless, include \"%s\" in your push comment." % (url, err, magicwords))
-        if repo.changectx('tip').description().find(magicwords) == -1:
-            return 1
-    return 0
deleted file mode 100644
--- a/mozhghooks/treeclosure_comm_central.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2013 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-from urllib2 import urlopen
-import os.path
-import re
-import json
-
-# Array of which directories SeaMonkey exclusively controls in comm-central
-seamonkeyOwns = [
-  'suite'
-]
-# Array of which directories Instantbird exclusively controls in comm-central
-instantbirdOwns = [
-  'im'
-]
-# Everything else is assumed to be controlled by Thunderbird.
-
-magicwords = "CLOSED TREE"
-
-treestatus_base_url = "https://treestatus.mozilla.org"
-
-def printError(message):
-    print "\n\n************************** ERROR ****************************"
-    print message
-    print "*************************************************************\n\n"
-
-# This function actually does the checking to see if a tree is closed or set
-# to approval required.
-def checkJsonTreeState(repo, repoName, appName):
-    name = os.path.basename(repo.root)
-    url = "%s/%s-%s?format=json" % (treestatus_base_url, name, appName)
-    try:
-        u = urlopen(url)
-        data = json.load(u)
-
-        if data['status'] == 'closed':
-            # The tree is closed
-
-            # Tell the pusher
-            print "Tree %s %s is CLOSED!" % (appName.capitalize(), name)
-            print repo.changectx('tip').description()
-
-            # Block the push if no magic words
-            if repo.changectx('tip').description().find(magicwords) == -1:
-                printError("To push despite the closed tree, include \"%s\" in your push comment" % magicwords)
-                return 1
-
-            # Otherwise let them push
-            print "But you included the magic words.  Hope you had permission!"
-            return 0
-
-        elif data['status'] == 'approval required':
-            # The tree needs approval
-
-            # If they've specified an approval or are backing out, let them push
-            dlower = repo.changectx('tip').description().lower()
-            if re.search('a\S*=', dlower) or dlower.startswith('back') or dlower.startswith('revert'):
-                return 0
-
-            # Otherwise tell them about the rule
-            printError("Pushing to an APPROVAL REQUIRED tree requires your top changeset comment to include: a=... (or, more accurately, a\\S*=...)")
-            return 1
-
-    except (ValueError, IOError), (err):
-        # fail closed if treestatus is down, unless the magic words have been used
-        printError("Error accessing %s :\n"
-                   "%s\n"
-                   "Unable to check if the tree is open - treating as if CLOSED.\n"
-                   "To push regardless, include \"%s\" in your push comment." % (url, err, magicwords))
-        if repo.changectx('tip').description().find(magicwords) == -1:
-            return 1
-
-    # By default the tree is open
-    return 0
-
-
-def isOwned(changedFile, ownerArray):
-    for dir in ownerArray:
-        if os.path.commonprefix([changedFile, dir]) == dir:
-            return True
-
-    return False
-
-def hook(ui, repo, node, **kwargs):
-    try:
-        # First find out which trees are affected
-        apps = { 'thunderbird' : False,
-                 'seamonkey' : False }
-
-        # all changesets from node to 'tip' inclusive are part of this push
-        rev = repo.changectx(node).rev()
-        tip = repo.changectx('tip').rev()
-        for i in range(rev, tip+1):
-            ctx = repo.changectx(i)
-            for changedFile in ctx.files():
-                if isOwned(changedFile, seamonkeyOwns):
-                    apps['seamonkey'] = True
-                elif isOwned(changedFile, instantbirdOwns):
-                    pass  # ignore Instantbird for tree closure reasons
-                else:
-                    apps['thunderbird'] = True
-
-        repoName = os.path.basename(repo.root)
-        status = 0
-
-        for app in apps:
-            if apps[app]:
-                status = checkJsonTreeState(repo, repoName, app)
-                if status == 1:
-                    return 1
-
-        return status;
-
-    except IOError, (err):
-        #TODO: Below obsolete?
-        # fail open, I guess. no sense making hg unavailable
-        # if the wiki is down
-        print "IOError: %s" % err
-        pass
-    return 0
deleted file mode 100755
--- a/mozhghooks/try_mandatory.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-
-chooserUrl = 'http://trychooser.pub.build.mozilla.org/'
-infoUrl = 'https://wiki.mozilla.org/Build:TryChooser'
-
-def printError(message):
-    print "\n\n************************** ERROR ****************************"
-    print message
-    print "*************************************************************\n\n"
-
-def hook(ui, repo, **kwargs):
-    # Block the push unless they use the try_syntax
-    # 'try: ' is enough to activate try_parser and get the default set
-    comment = repo.changectx('tip').description()
-    info = { 'chooserUrl': chooserUrl, 'infoUrl': infoUrl }
-    if "try: " not in comment:
-        printError("""To push to try you must use try syntax in the push comment of the *last* change 
-See %(chooserUrl)s to build your syntax
-For assistance using the syntax, see %(infoUrl)s.
-Thank you for helping to reduce CPU cyles by asking for exactly what you need.""" % info)
-        return 1
-    elif "-p none" in comment:
-        printError("""Your try syntax contains '-p none', which would not trigger any jobs.
-Please try try again. If you *intended* to push without triggering
-any jobs, use -p any_invalid_syntax. For assistance with try server
-syntax, see %(infoUrl)s.""" % info)
-        return 1
-    else:
-        print """Looks like you used try syntax, going ahead with the push.
-If you don't get what you expected, check %(chooserUrl)s
-for help with building your trychooser request.
-Thanks for helping save resources, you're the best!""" % info
-        return 0
deleted file mode 100644
--- a/mozhghooks/whitelist_qa.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2010 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
-# USA.
-
-# This script implements a whitelist containing people from the QA team (plus
-# Dustin)
-#
-# run `python setup.py install` to install the module in the proper place,
-# and then modify the repository's hgrc as per example-hgrc.
-
-import os
-
-ALLOWED_USERS = set([
-    'dmitchell@mozilla.com',
-    'hskupin@mozilla.com',
-])
-
-
-def hook(ui, repo, node=None, **kwargs):
-    rev = repo[node].rev()
-    tip = repo['tip'].rev()
-    branches = set(repo.changectx(i).branch() for i in range(rev, tip + 1))
-    if 'production' in branches and os.environ['USER'] not in ALLOWED_USERS:
-        print "** you (%s) are not allowed to push to the production branch" \
-            % (os.environ['USER'],)
-        return 1
-    return 0
deleted file mode 100644
--- a/mozhghooks/whitelist_releng.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2010 Mozilla Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
-# USA.
-
-# This script implements a whitelist containing people from the releng and
-# relops teams.
-#
-# run `python setup.py install` to install the module in the proper place,
-# and then modify the repository's hgrc as per example-hgrc.
-
-import os
-
-ALLOWED_USERS = set([
-    'Callek@gmail.com',
-    'arich@mozilla.com',
-    'armenzg@mozilla.com',
-    'asasaki@mozilla.com',
-    'bhearsum@mozilla.com',
-    'catlee@mozilla.com',
-    'coop@mozilla.com',
-    'dmitchell@mozilla.com',
-    'hwine@mozilla.com',
-    'jlund@mozilla.com',
-    'jozeller@mozilla.com',
-    'jwatkins@mozilla.com',
-    'jwood@mozilla.com',
-    'kmoir@mozilla.com',
-    'mcornmesser@mozilla.com',
-    'mgervasini@mozilla.com',
-    'mshal@mozilla.com',
-    'nthomas@mozilla.com',
-    'pmoore@mozilla.com',
-    'qfortier@mozilla.com',
-    'raliiev@mozilla.com',
-    'sbruno@mozilla.com',
-])
-
-
-def hook(ui, repo, node=None, **kwargs):
-    rev = repo[node].rev()
-    tip = repo['tip'].rev()
-    branches = set(repo.changectx(i).branch() for i in range(rev, tip + 1))
-    if 'production' in branches and os.environ['USER'] not in ALLOWED_USERS:
-        print "** you (%s) are not allowed to push to the production branch" \
-            % (os.environ['USER'],)
-        return 1
-    return 0
deleted file mode 100755
--- a/runtests.py
+++ /dev/null
@@ -1,1003 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import with_statement
-import unittest
-from mercurial import ui, hg, commands, util
-from mercurial.commands import add, clone, commit, init, push, rename, remove, update, merge
-from mercurial.node import hex, short
-from tempfile import mkdtemp, mkstemp
-import shutil
-import os, stat
-from os.path import join, exists
-import sqlite3 as sqlite
-from getpass import getuser
-from time import time
-import urllib2
-from StringIO import StringIO
-
-def addHook(repodir, hook):
-  with open(join(repodir, '.hg', 'hgrc'), 'w') as f:
-    f.write("""[hooks]
-pretxnchangegroup.z_linearhistory = python:mozhghooks.%s
-""" % hook)
-
-def appendFile(filename, content):
-  try:
-    os.makedirs(os.path.dirname(filename))
-  except:
-    pass
-  with open(filename, 'a') as f:
-    f.write(content)
-
-def removeFromFile(filename, content):
-  try:
-    os.makedirs(os.path.dirname(filename))
-  except:
-    pass
-  newlines = []
-  with open(filename, 'r') as f:
-    lines = f.readlines()
-    for line in lines:
-        if line != content:
-            newlines.append(line)
-  with open(filename, 'a') as f:
-    f.write(''.join(newlines))
-
-def editFile(filename, original, updated):
-  try:
-    os.makedirs(os.path.dirname(filename))
-  except:
-    pass
-  newlines = []
-  with open(filename, 'r') as f:
-    lines = f.readlines()
-    for line in lines:
-        if line == original:
-            newlines.append(updated)
-        else:
-            newlines.append(line)
-  with open(filename, 'a') as f:
-    f.write(''.join(newlines))
-
-def getPushesFromDB(repo):
-  conn = sqlite.connect(join(repo.root, '.hg', 'pushlog2.db'))
-  res = conn.execute("SELECT id, user, date, rev, node from pushlog INNER JOIN changesets on pushlog.id = changesets.pushid ORDER BY id")
-  s = set()
-  pushes = []
-  for row in res.fetchall():
-    if row[0] not in s:
-      pushes.append({'id':row[0],
-                     'user':row[1],
-                     'date':row[2],
-                     'changes':[]})
-      s.add(row[0])
-    pushes[-1]['changes'].append({'rev':row[3], 'node':row[4]})
-  return pushes
-
-class TestPushlogHook(unittest.TestCase):
-  def setUp(self):
-    self.ui = ui.ui()
-    self.ui.quiet = True
-    self.ui.verbose = False
-    self.repodir = mkdtemp(prefix="hg-test")
-    init(self.ui, dest=self.repodir)
-    addHook(self.repodir, "pushlog.log")
-    self.repo = hg.repository(self.ui, self.repodir)
-    self.clonedir = mkdtemp(prefix="hg-test")
-    clone(self.ui, self.repo, self.clonedir)
-    self.clonerepo = hg.repository(self.ui, self.clonedir)
-
-  def tearDown(self):
-    shutil.rmtree(self.repodir)
-    shutil.rmtree(self.clonedir)
-
-  def testBasic(self):
-    """Push one changeset, sanity check all the data."""
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    start = time()
-    push(u, self.clonerepo, dest=self.repodir)
-    end = time()
-    p = getPushesFromDB(self.repo)
-    self.assertEqual(len(p), 1)
-    self.assertEqual(len(p[0]['changes']), 1)
-    self.assertEqual(p[0]['user'], getuser())
-    # tough to assert exactly
-    self.assert_(p[0]['date'] >= int(start))
-    self.assert_(p[0]['date'] <= int(end))
-    c = p[0]['changes'][0]
-    tip = self.clonerepo.changectx('tip')
-    self.assertEqual(c['rev'], tip.rev())
-    self.assertEqual(c['node'], hex(tip.node()))
-
-  def testTwoPushes(self):
-    """Push two changesets in two pushes, sanity check all the data."""
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    push(u, self.clonerepo, dest=self.repodir)
-
-    appendFile(join(self.clonedir, "testfile"), "checkin 2")
-    commit(u, self.clonerepo, message="checkin 2 bug 23456")
-    push(u, self.clonerepo, dest=self.repodir)
-
-    pushes = getPushesFromDB(self.repo)
-    self.assertEqual(len(pushes), 2)
-    self.assert_(all(len(p['changes']) == 1 for p in pushes))
-    self.assert_(all(p['user'] == getuser() for p in pushes))
-    self.assert_(pushes[0]['date'] <= pushes[1]['date'])
-    self.assert_(pushes[0]['changes'][0]['rev'] <= pushes[1]['changes'][0]['rev'])
-    # check that all the node/rev pairs we recorded match what hg thinks
-    self.assert_(all(self.clonerepo.changectx(c['node']).rev() == c['rev'] for p in pushes for c in p['changes']))
-
-  def testTwoChangesOnePush(self):
-    """Push two changesets in one push, sanity check all the data."""
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    appendFile(join(self.clonedir, "testfile"), "checkin 2")
-    commit(u, self.clonerepo, message="checkin 2 bug 23456")
-    start = time()
-    push(u, self.clonerepo, dest=self.repodir)
-    end = time()
-
-    pushes = getPushesFromDB(self.repo)
-    self.assertEqual(len(pushes), 1)
-    p = pushes[0]
-    self.assertEqual(len(p['changes']), 2)
-    self.assertEqual(p['user'], getuser())
-    self.assert_(p['date'] >= int(start))
-    self.assert_(p['date'] <= int(end))
-    self.assert_(p['changes'][0]['rev'] <= p['changes'][1]['rev'])
-    # check that all the node/rev pairs we recorded match what hg thinks
-    self.assert_(all(self.clonerepo.changectx(c['node']).rev() == c['rev'] for c in p['changes']))
-
-  def testPushlogPermissions(self):
-    """Check that the pushlog db is group writable after pushing."""
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    push(u, self.clonerepo, dest=self.repodir)
-
-    st = os.stat(join(self.repodir, ".hg", "pushlog2.db"))
-    self.assertEqual(st.st_mode & stat.S_IWGRP, stat.S_IWGRP)
-
-  def testEmptyDB(self):
-    """bug 466149 - Check that pushing to a db without a schema succeeds."""
-    u = self.ui
-    # empty the db file
-    with open(join(self.repodir, ".hg", "pushlog2.db"), 'w') as f:
-      pass
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    push(u, self.clonerepo, dest=self.repodir)
-
-    p = getPushesFromDB(self.repo)
-    self.assertEqual(len(p), 1)
-    self.assertEqual(len(p[0]['changes']), 1)
-
-  def testDBLocking(self):
-    """bug 508863 - Lock the DB and try to push, check that the error doesn't suck so much."""
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    push(u, self.clonerepo, dest=self.repodir)
-
-    # open the repo and insert something to lock it
-    conn = sqlite.connect(join(self.repo.root, '.hg', 'pushlog2.db'))
-    conn.execute("INSERT INTO pushlog (user, date) VALUES('user', 0)")
-
-    appendFile(join(self.clonedir, "testfile"), "checkin 2")
-    commit(u, self.clonerepo, message="checkin 2 bug 23456")
-    sawError = False
-    #TODO: would be nice if we could lower the timeout
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-    conn.commit()
-    # this one should succeed
-    push(u, self.clonerepo, dest=self.repodir)
-    conn.close()
-
-class ClosureHookTestHelpers:
-  """A mixin that provides a director class so we can intercept urlopen and
-     change the result for our tests."""
-  def setUp(self):
-    # add a urllib OpenerDirector so we can intercept urlopen
-    class MyDirector:
-      expected = []
-      opened = 0
-      def open(self, url, data=None, timeout=None):
-        expectedURL, sendData = self.expected.pop()
-        """
-        If this is ever changed so that more than one url are allowed, then
-        the comm-central tests must be re-evaluated as they currently rely
-        on it.
-        """
-        if expectedURL != url:
-          raise Exception("Incorrect URL, got %s expected %s!" % (url, expectedURL))
-        self.opened += 1
-        return StringIO(sendData)
-      def expect(self, url, data):
-        """
-        Indicate that the next url opened should be |url|, and should return
-        |data| as its contents.
-        """
-        self.expected.append((url, data))
-    self.director = MyDirector()
-    urllib2.install_opener(self.director)
-
-  def tearDown(self):
-    urllib2.install_opener(urllib2.OpenerDirector())
-
-  def redirect(self, url, data):
-    self.director.expect(url, data)
-
-class TestTreeClosureHook(ClosureHookTestHelpers, unittest.TestCase):
-  def setUp(self):
-    self.ui = ui.ui()
-    self.ui.quiet = True
-    self.ui.verbose = False
-    self.repodirbase = mkdtemp(prefix="hg-test")
-    #XXX: sucks, but tests can rename it if they'd like to test something else
-    self.repodir = join(self.repodirbase, "mozilla-central")
-    init(self.ui, dest=self.repodir)
-    addHook(self.repodir, "treeclosure.hook")
-    self.repo = hg.repository(self.ui, self.repodir)
-    self.clonedir = mkdtemp(prefix="hg-test")
-    clone(self.ui, self.repo, self.clonedir)
-    self.clonerepo = hg.repository(self.ui, self.clonedir)
-    ClosureHookTestHelpers.setUp(self)
-
-  def tearDown(self):
-    shutil.rmtree(self.repodirbase)
-    shutil.rmtree(self.clonedir)
-    ClosureHookTestHelpers.tearDown(self)
-
-  def testOpen(self):
-    """Pushing to an OPEN tree should succeed."""
-    self.redirect("https://treestatus.mozilla.org/mozilla-central?format=json",
-                '{"status": "open", "reason": null}')
-
-    # pushing something should now succeed
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1")
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-  def testClosed(self):
-    """Pushing to a CLOSED tree should fail."""
-    self.redirect("https://treestatus.mozilla.org/mozilla-central?format=json",
-                '{"status": "closed", "reason": "splines won\'t reticulate"}')
-    # pushing something should now fail
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-  def testClosedMagicWords(self):
-    """
-    Pushing to a CLOSED tree with 'CLOSED TREE' in the commit message
-    should succeed.
-    """
-    self.redirect("https://treestatus.mozilla.org/mozilla-central?format=json",
-                '{"status": "closed", "reason": "too many widgets"}')
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 CLOSED TREE")
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-  def testClosedMagicWordsTip(self):
-    """
-    Pushing multiple changesets to a CLOSED tree with 'CLOSED TREE'
-    in the commit message of the tip changeset should succeed.
-    """
-    self.redirect("https://treestatus.mozilla.org/mozilla-central?format=json",
-                '{"status": "closed", "reason": "the end of the world as we know it"}')
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1")
-    appendFile(join(self.clonedir, "testfile"), "checkin 2")
-    commit(u, self.clonerepo, message="checkin 2 CLOSED TREE")
-
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-  def testApprovalRequired(self):
-    """Pushing to an APPROVAL REQUIRED tree should fail."""
-    self.redirect("https://treestatus.mozilla.org/mozilla-central?format=json",
-                '{"status": "approval required", "reason": "be verrrry careful"}')
-    # pushing something should now fail
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-  def testApprovalRequiredMagicWords(self):
-    """
-    Pushing to an APPROVAL REQUIRED tree with a=foo
-    in the commit message should succeed.
-    """
-    self.redirect("https://treestatus.mozilla.org/mozilla-central?format=json",
-                '{"status": "approval required", "reason": "trees are fragile"}')
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 a=someone")
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-    # also check that approval of the form a1.2=foo works
-    self.redirect("https://treestatus.mozilla.org/mozilla-central?format=json",
-                '{"status": "approval required", "reason": "like they\'re made of glass"}')
-    appendFile(join(self.clonedir, "testfile"), "checkin 2")
-    commit(u, self.clonerepo, message="checkin 2 a1.2=someone")
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 2)
-
-  def testApprovalRequiredMagicWordsTip(self):
-    """
-    Pushing to an APPROVAL REQUIRED tree with a=foo
-    in the commit message of the tip changeset should succeed.
-    """
-    self.redirect("https://treestatus.mozilla.org/mozilla-central?format=json",
-                '{"status": "approval required", "reason": "stained glass"}')
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1")
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    commit(u, self.clonerepo, message="checkin 2 a=someone")
-
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-class TestTreeCommCentralClosureHook(ClosureHookTestHelpers, unittest.TestCase):
-  def setUp(self):
-    self.ui = ui.ui()
-    self.ui.quiet = True
-    self.ui.verbose = False
-    self.repodirbase = mkdtemp(prefix="hg-test")
-    #XXX: sucks, but tests can rename it if they'd like to test something else
-    self.repodir = join(self.repodirbase, "comm-central")
-    init(self.ui, dest=self.repodir)
-    addHook(self.repodir, "treeclosure_comm_central.hook")
-    self.repo = hg.repository(self.ui, self.repodir)
-    self.clonedir = mkdtemp(prefix="hg-test")
-    clone(self.ui, self.repo, self.clonedir)
-    self.clonerepo = hg.repository(self.ui, self.clonedir)
-    ClosureHookTestHelpers.setUp(self)
-
-  def tearDown(self):
-    shutil.rmtree(self.repodirbase)
-    shutil.rmtree(self.clonedir)
-    ClosureHookTestHelpers.tearDown(self)
-
-  def actualTestCCOpen(self, treeName, fileInfo):
-    """Pushing to an OPEN CC tree should succeed."""
-    # If this tests attempts to pull something that isn't treeName, then the
-    # re-director should fail for us. Hence we know that the hook is only
-    # pulling the predefined tree and nothing else.
-    self.redirect("https://treestatus.mozilla.org/comm-central-" + treeName.lower() + "?format=json",
-                  '{"status": "open", "reason": null}')
-
-    # pushing something should now succeed
-    u = self.ui
-
-    fileName = fileInfo.pop()
-    fileLoc = self.clonedir
-    for dir in fileInfo:
-      fileLoc = join(fileLoc, dir)
-      os.mkdir(fileLoc)
-
-    fileLoc = join(fileLoc, fileName)
-
-    appendFile(fileLoc, "checkin 1")
-    add(u, self.clonerepo, fileLoc)
-    commit(u, self.clonerepo, message="checkin 1")
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
- 
-  def testCCOpenThunderbird(self):
-    self.actualTestCCOpen("Thunderbird", ["testfile"])
-
-  def testCCOpenSeaMonkey(self):
-    self.actualTestCCOpen("SeaMonkey", ["suite", "build", "test"])
-
-  def testCCOpenCalendar(self):
-    # Calendar is now built alongside Thunderbird
-    self.actualTestCCOpen("Thunderbird", ["calendar", "app", "test"])
-
-  def actualTestCCClosed(self, treeName, fileInfo):
-    """Pushing to a CLOSED CC tree should fail."""
-    # If this tests attempts to pull something that isn't treeName, then the
-    # re-director should fail for us. Hence we know that the hook is only
-    # pulling the predefined tree and nothing else.
-    self.redirect("https://treestatus.mozilla.org/comm-central-" + treeName.lower() + "?format=json",
-                  '{"status": "closed", "reason": null}')
-
-    # pushing something should now fail
-    u = self.ui
-
-    fileName = fileInfo.pop()
-    fileLoc = self.clonedir
-    for dir in fileInfo:
-      fileLoc = join(fileLoc, dir)
-      os.mkdir(fileLoc)
-
-    fileLoc = join(fileLoc, fileName)
-
-    appendFile(fileLoc, "checkin 1")
-    add(u, self.clonerepo, fileLoc)
-    commit(u, self.clonerepo, message="checkin 1")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-  def testCCClosedThunderbird(self):
-    self.actualTestCCClosed("Thunderbird", ["testfile"])
-
-  def testCCClosedSeaMonkey(self):
-    self.actualTestCCClosed("SeaMonkey", ["suite", "build", "test"])
-
-  def testCCClosedCalendar(self):
-    # Calendar is now built alongside Thunderbird
-    self.actualTestCCClosed("Thunderbird", ["calendar", "app", "test"])
-
-  # In theory adding CLOSED TREE is the same code-path for all projects,
-  # so just checking for one project
-  def testCCClosedThunderbirdMagicWords(self):
-    """
-    Pushing to a CLOSED Thunderbird tree with 'CLOSED TREE' in the commit message
-    should succeed.
-    """
-    self.redirect("https://treestatus.mozilla.org/comm-central-thunderbird?format=json",
-                  '{"status": "closed", "reason": null}')
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 CLOSED TREE")
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-  # In theory adding CLOSED TREE is the same code-path for all projects,
-  # so just checking for one project
-  def testCCClosedThunderbirdMagicWordsTip(self):
-    """
-    Pushing multiple changesets to a CLOSED Thunderbird tree with 'CLOSED TREE'
-    in the commit message of the tip changeset should succeed.
-    """
-    self.redirect("https://treestatus.mozilla.org/comm-central-thunderbird?format=json",
-                  '{"status": "closed", "reason": null}')
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1")
-    appendFile(join(self.clonedir, "testfile"), "checkin 2")
-    commit(u, self.clonerepo, message="checkin 2 CLOSED TREE")
-
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-  def testCCApprovalRequired(self):
-    """Pushing to an APPROVAL REQUIRED tree should fail."""
-    self.redirect("https://treestatus.mozilla.org/comm-central-thunderbird?format=json",
-                  '{"status": "approval required", "reason": null}')
-    # pushing something should now fail
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-  def testCCApprovalRequiredMagicWords(self):
-    """
-    Pushing to an APPROVAL REQUIRED tree with a=foo
-    in the commit message should succeed.
-    """
-    self.redirect("https://treestatus.mozilla.org/comm-central-thunderbird?format=json",
-                  '{"status": "approval required", "reason": null}')
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 a=someone")
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-    # also check that approval of the form a1.2=foo works
-    self.redirect("https://treestatus.mozilla.org/comm-central-thunderbird?format=json",
-                  '{"status": "approval required", "reason": null}')
-    appendFile(join(self.clonedir, "testfile"), "checkin 2")
-    commit(u, self.clonerepo, message="checkin 2 a1.2=someone")
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 2)
-
-  def testCCApprovalRequiredMagicWordsTip(self):
-    """
-    Pushing to an APPROVAL REQUIRED tree with a=foo
-    in the commit message of the tip changeset should succeed.
-    """
-    self.redirect("https://treestatus.mozilla.org/comm-central-thunderbird?format=json",
-                  '{"status": "approval required", "reason": null}')
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1")
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    commit(u, self.clonerepo, message="checkin 2 a=someone")
-
-    push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(self.director.opened, 1)
-
-class TestTryMandatoryHook(ClosureHookTestHelpers, unittest.TestCase):
-  def setUp(self):
-    self.ui = ui.ui()
-    self.ui.quiet = True
-    self.ui.verbose = False
-    self.repodir = mkdtemp(prefix="hg-test")
-    init(self.ui, dest=self.repodir)
-    addHook(self.repodir, "try_mandatory.hook")
-    self.repo = hg.repository(self.ui, self.repodir)
-    self.clonedir = mkdtemp(prefix="hg-test")
-    clone(self.ui, self.repo, self.clonedir)
-    self.clonerepo = hg.repository(self.ui, self.clonedir)
-    ClosureHookTestHelpers.setUp(self)
-
-  def tearDown(self):
-    shutil.rmtree(self.repodir)
-    shutil.rmtree(self.clonedir)
-    ClosureHookTestHelpers.tearDown(self)
-
-  def testWithoutTrySyntax(self):
-    """Push one changeset, without using the try syntax should error."""
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-
-  def testWithTrySyntax(self):
-    """Push one changeset, with using the try syntax should succeed."""
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(u, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(u, self.clonerepo, message="checkin 1 try: -b do -p all")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-class TestCommitMessageHook(unittest.TestCase):
-  def setUp(self):
-    self.ui = ui.ui()
-    self.ui.quiet = True
-    self.ui.verbose = False
-    self.repodir = mkdtemp(prefix="hg-TestCommitMessageHook")
-    init(self.ui, dest=self.repodir)
-    addHook(self.repodir, "commit-message.hook")
-    self.repo = hg.repository(self.ui, self.repodir)
-    self.clonedir = mkdtemp(prefix="hg-test")
-    clone(self.ui, self.repo, self.clonedir)
-    self.clonerepo = hg.repository(self.ui, self.clonedir)
-    
-  def tearDown(self):
-    shutil.rmtree(self.repodir)
-    shutil.rmtree(self.clonedir)
-    
-  def testWithBug(self):
-    """ Every test should have bug # like "Bug 111", "Bug #111" or "b=111". """
-
-    ui = self.ui
-    messages = [
-      "Bug 603517 - Enable mochitest to optionally run in loops without restarting the browser r=ctalbert",
-      "Bug #123456 - add test",
-      "b=630117, rename typed array slice() -> subset(); r=jwalden, a=block"
-      "ARM assembler tweaks. (b=588021, r=cdleary)"
-    ]
-
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(ui, self.clonerepo, join(self.clonedir, "testfile"))
-    for message in messages:
-      commit(ui, self.clonerepo, message=message)
-
-    result = push(ui, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testBackout(self):
-    """ Test different ways of spelling backout (and revert). """
-
-    ui = self.ui
-    messages = [
-      "Backed out changeset 593d94e9492e",
-      "Backout changesets 9e4ab3907b29, 3abc0dbbf710 due to m-oth permaorange",
-      "Backout of 35a679df430b due to bustage",
-      "backout 68941:5b8ade677818", # including the local numeric ID is silly but harmless
-      
-      # we do not have a lot of reverts "hg log | grep revert" without a bug #
-      "Revert to changeset a87ee7550f6a due to incomplete backout" 
-    ]
-    
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(ui, self.clonerepo, join(self.clonedir, "testfile"))
-    for message in messages:
-      commit(ui, self.clonerepo, message=message)
-    result = push(ui, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-    
-  def testSpecial(self):
-    """ Test some special stuff like "no bug", "add tag" or "update nanojit-import-rev stamp". """
-
-    ui = self.ui
-    messages = [
-      "Added tag AURORA_BASE_20110412 for changeset a95d42642281",
-      "Fix typo in comment within nsFrame.cpp (no bug) rs=dbaron DONTBUILD",
-      "Fix ARM assert (no bug, r=cdleary).",
-      "Backout 3b59c196aaf9 - no bug # in commit message"
-    ]
-
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(ui, self.clonerepo, join(self.clonedir, "testfile"))
-    for message in messages:
-      commit(ui, self.clonerepo, message=message)
-    result = push(ui, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  bad = [
-    "Mass revert m-i to the last known good state",
-    "update revision of Add-on SDK tests to latest tip; test-only",
-    "Fix stupid bug in foo::bar()",
-    "First line does not have a bug number\n\nbug 123456",
-    "imported patch phishingfixes",
-    "imported patch 441197-1",
-    "Back out Dao's push because of build bustage",
-    "Bump mozilla-central version numbers for the next release on a CLOSED TREE.",
-    "Bump Sync version to 1.9.0. r=me",
-    "checkin 1 try: -b do -p all"
-  ]
-
-  def testShouldFail(self):
-    """ Some commit messages that should explicitly not pass anymore. """
-
-    ui = self.ui
-    
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(ui, self.clonerepo, join(self.clonedir, "testfile"))
-    
-    for message in self.bad:
-      appendFile(join(self.clonedir, "testfile"), "checkin 1")
-      commit(ui, self.clonerepo, message=message)
-      print message
-      self.assertRaises(util.Abort, push, ui, self.clonerepo, dest=self.repodir)
-      
-  def testIgnore(self):
-    """ Test that IGNORE BAD COMMIT MESSAGES works """
-    ui = self.ui
-    
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(ui, self.clonerepo, join(self.clonedir, "testfile"))
-    
-    for message in self.bad:
-      appendFile(join(self.clonedir, "testfile"), "checkin 1")
-      commit(ui, self.clonerepo, message=message)
-    
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    commit(ui, self.clonerepo, message="IGNORE BAD COMMIT MESSAGES")
-
-    result = push(ui, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-class TestCaseOnlyRenameHook(unittest.TestCase):
-  def setUp(self):
-    self.ui = ui.ui()
-    self.ui.quiet = True
-    self.ui.verbose = False
-    self.repodir = mkdtemp(prefix="hg-TestCaseOnlyRenameHook")
-    init(self.ui, dest=self.repodir)
-    addHook(self.repodir, "prevent_case_only_renames.hook")
-    self.repo = hg.repository(self.ui, self.repodir)
-    self.clonedir = mkdtemp(prefix="hg-test")
-    clone(self.ui, self.repo, self.clonedir)
-    self.clonerepo = hg.repository(self.ui, self.clonedir)
-
-  def tearDown(self):
-    shutil.rmtree(self.repodir)
-    shutil.rmtree(self.clonedir)
-
-  def testTipShouldFail(self):
-    """ Test that a case-only rename in tip should fail. """
-
-    ui = self.ui
-
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(ui, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(ui, self.clonerepo, message="checkin 1")
-    rename(ui, self.clonerepo,
-           join(self.clonedir, "testfile"),
-           join(self.clonedir, "TESTFILE"));
-    commit(ui, self.clonerepo, message="checkin 2")
-    self.assertRaises(util.Abort, push, ui, self.clonerepo, dest=self.repodir)
-
-  def testTipDirRenameShouldFail(self):
-    """ Test that a case-only directory rename in tip should fail. """
-
-    # Disable the test on case insensitive filesystems
-    tmphandle, tmppath = mkstemp()
-    if exists(tmppath.upper()):
-      return
-
-    ui = self.ui
-
-    appendFile(join(self.clonedir, "testdir/testfile"), "checkin 1")
-    add(ui, self.clonerepo, join(self.clonedir, "testdir/testfile"))
-    commit(ui, self.clonerepo, message="checkin 1")
-    rename(ui, self.clonerepo,
-           join(self.clonedir, "testdir/testfile"),
-           join(self.clonedir, "TESTDIR/testfile"));
-    commit(ui, self.clonerepo, message="checkin 2")
-    self.assertRaises(util.Abort, push, ui, self.clonerepo, dest=self.repodir)
-
-  def testPreviousShouldFail(self):
-    """ Test that a case-only rename that's not tip should fail. """
-
-    ui = self.ui
-
-    appendFile(join(self.clonedir, "testfile"), "checkin 1")
-    add(ui, self.clonerepo, join(self.clonedir, "testfile"))
-    commit(ui, self.clonerepo, message="checkin 1")
-
-    rename(ui, self.clonerepo,
-           join(self.clonedir, "testfile"),
-           join(self.clonedir, "TESTFILE"));
-    commit(ui, self.clonerepo, message="checkin 2")
-
-    appendFile(join(self.clonedir, "TESTFILE"), "checkin 3")
-    commit(ui, self.clonerepo, message="checkin 3")
-
-    self.assertRaises(util.Abort, push, ui, self.clonerepo, dest=self.repodir)
-
-class TestPreventUUIDHook(unittest.TestCase):
-  def setUp(self):
-    self.ui = ui.ui()
-    self.ui.quiet = True
-    self.ui.verbose = False
-    self.repodir = mkdtemp(prefix="hg-TestPreventUUIDHook")
-    init(self.ui, dest=self.repodir)
-    addHook(self.repodir, "prevent_uuid_changes.hook")
-    self.repo = hg.repository(self.ui, self.repodir)
-    self.clonedir = mkdtemp(prefix="hg-test")
-    clone(self.ui, self.repo, self.clonedir)
-    self.clonerepo = hg.repository(self.ui, self.clonedir)
-    # Create a pre-existing repo with a file that contains UUID
-    appendFile(join(self.clonedir, "original.idl"), "uuid(abc123)")
-    add(self.ui, self.clonerepo, join(self.clonedir, "original.idl"))
-    commit(self.ui, self.clonerepo, message="original repo commit ba=me")
-    push(self.ui, self.clonerepo, dest=self.repodir)
-    print "===== In method", self._testMethodName, " ======="
-
-  def tearDown(self):
-    shutil.rmtree(self.repodir)
-    shutil.rmtree(self.clonedir)
-
-  def testUUIDEditExistingShouldFail(self):
-    """ Test that editing .idl file with 'uuid(' and no 'ba=' should fail  """
-    u = self.ui
-    editFile(join(self.clonedir, "original.idl"), "uuid(abc123)", "uuid(def456)")
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-
-  def testUUIDEditExistingShouldPass(self):
-    """ Test that editing .idl file with 'uuid(' with ba=... should pass """
-    u = self.ui
-    editFile(join(self.clonedir, "original.idl"), "uuid(abc123)", "uuid(def456)")
-    commit(u, self.clonerepo, message="checkin 1 bug 12345 ba=me")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testUUIDMultiplePushShouldFail(self):
-    """ Test that adding .idl file with uuid with other files and no 'ba=' should fail  """
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile1.idl"), "uuid(something here)")
-    add(u, self.clonerepo, join(self.clonedir, "testfile1.idl"))
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    appendFile(join(self.clonedir, "testfile2.txt"), "checkin2")
-    add(u, self.clonerepo, join(self.clonedir, "testfile2.txt"))
-    commit(u, self.clonerepo, message="checkin 2 bug 12345")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-
-  def testUUIDMultiplePushShouldPass(self):
-    """ Test that changeset with 'uuid(' change in .idl should pass if 'ba=...' is in the push comment """
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile3.idl"), "uuid(something here)")
-    add(u, self.clonerepo, join(self.clonedir, "testfile3.idl"))
-    commit(u, self.clonerepo, message="checkin 3 bug 12345")
-    appendFile(join(self.clonedir, "testfile2.txt"), "checkin2")
-    add(u, self.clonerepo, join(self.clonedir, "testfile2.txt"))
-    commit(u, self.clonerepo, message="checkin 2 bug 12345 ba=approver")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testUUIDNonIDLShouldPass(self):
-    """ Test that changeset with 'uuid(' change in a file not ending in .idl should pass """
-    u = self.ui
-    appendFile(join(self.clonedir, "testfile1.txt"), "uuid(something here)")
-    add(u, self.clonerepo, join(self.clonedir, "testfile1.txt"))
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testUUIDRemoveUUIDNoApprovalShouldFail(self):
-    """ Test that changeset with 'uuid(' removed from file ending in .idl should fail """
-    u = self.ui
-    appendFile(join(self.clonedir, "original.idl"), "line of text")
-    removeFromFile(join(self.clonedir, "original.idl"), "uuid(abc123)")
-    commit(u, self.clonerepo, message="checkin removed uuid bug 12345")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-
-  def testUUIDRemoveUUIDWithApprovalShouldPass(self):
-    """ Test that changeset with 'uuid(' removed from file ending in .idl should pass with ba=... """
-    u = self.ui
-    appendFile(join(self.clonedir, "original.idl"), "line of text")
-    removeFromFile(join(self.clonedir, "original.idl"), "uuid(abc123)")
-    commit(u, self.clonerepo, message="checkin removed uuid bug 12345 ba=me")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testUUIDDeletedIDLApproveShouldPass(self):
-    """ Test that changeset with .idl file removed should pass with ba= approval """
-    u = self.ui
-    remove(u, self.clonerepo, join(self.clonedir, "original.idl"))
-    commit(u, self.clonerepo, message="checkin 2 removed idl file ba=approver")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testUUIDDeletedIDLNoApproveShouldFail(self):
-    """ Test that changeset with .idl file removed should fail without approval"""
-    u = self.ui
-    remove(u, self.clonerepo, join(self.clonedir, "original.idl"))
-    commit(u, self.clonerepo, message="checkin 2 removed idl file ")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-
-class TestPreventWebIDLHook(unittest.TestCase):
-  def setUp(self):
-    self.ui = ui.ui()
-    self.ui.quiet = True
-    self.ui.verbose = False
-    self.repodir = mkdtemp(prefix="hg-TestPreventWebIDLHook")
-    init(self.ui, dest=self.repodir)
-    addHook(self.repodir, "prevent_webidl_changes.hook")
-    self.repo = hg.repository(self.ui, self.repodir)
-    self.clonedir = mkdtemp(prefix="hg-test")
-    clone(self.ui, self.repo, self.clonedir)
-    self.clonerepo = hg.repository(self.ui, self.clonedir)
-    # Create a pre-existing repo with a file that contains UUID
-    appendFile(join(self.clonedir, "original.webidl"), "interface Foo{};")
-    add(self.ui, self.clonerepo, join(self.clonedir, "original.webidl"))
-    appendFile(join(self.clonedir, "dummy"), "foo")
-    add(self.ui, self.clonerepo, join(self.clonedir, "dummy"))
-    commit(self.ui, self.clonerepo, message="original repo commit r=jst")
-    push(self.ui, self.clonerepo, dest=self.repodir)
-
-  def tearDown(self):
-    shutil.rmtree(self.repodir)
-    shutil.rmtree(self.clonedir)
-
-  def testWebIDLEditWithoutReviewShouldFail(self):
-    """ Test that editing .webidl file without review should fail """
-    u = self.ui
-    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 12345")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-
-  def testWebIDLEditWithoutProperReviewShouldFail(self):
-    """ Test that editing .webidl file without proper DOM peer review should fail """
-    u = self.ui
-    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 12345; r=foobar")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-
-  def testWebIDLEditWithoutReviewFromDOMPeerShouldPass(self):
-    """ Test that editing .webidl file by DOM peers without review should pass """
-    u = self.ui
-    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 12345", user="Johnny Stenback <jst@mozilla.com>")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testWebIDLEditWithoutProperReviewInReleaseMergeShouldPass(self):
-    """ Test that editing .webidl file without proper DOM peer review when doing a code uplift should pass """
-    u = self.ui
-    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 12345; r=foobar")
-    appendFile(join(self.clonedir, "dummy"), "foo")
-    add(u, self.clonerepo, join(self.clonedir, "dummy"))
-    commit(u, self.clonerepo, message="Doing the code uplift, a=release")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testWebIDLEditWithoutProperReviewInNonReleaseMergeButWithAEqualsReleaseShouldFail(self):
-    """ Test that editing .webidl file without proper DOM peer review when doing a code uplift should pass """
-    u = self.ui
-    appendFile(join(self.clonedir, "dummy"), "foo")
-    add(u, self.clonerepo, join(self.clonedir, "dummy"))
-    commit(u, self.clonerepo, message="Doing the code uplift, a=release")
-    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 12345; r=foobar")
-    self.assertRaises(util.Abort, push, u, self.clonerepo, dest=self.repodir)
-
-  def testWebIDLEditWithProperReviewShouldPass(self):
-    """ Test that editing .webidl file with proper DOM peer review should pass """
-    u = self.ui
-    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 12345; r=foobar,jst")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-    editFile(join(self.clonedir, "original.webidl"), "interface Bar{};", "interface Baz{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 67890; r=foobar r=jst")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-    editFile(join(self.clonedir, "original.webidl"), "interface Baz{};", "interface Bizarre{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 123456; r=foobar r=lumpy,jst")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    editFile(join(self.clonedir, "original.webidl"), "interface Bizarre{};", "interface Bar{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 123450; sr=foobar,jst")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-    editFile(join(self.clonedir, "original.webidl"), "interface Bar{};", "interface Baz{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 678900; sr=foobar sr=jst")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-    editFile(join(self.clonedir, "original.webidl"), "interface Baz{};", "interface Bizarre{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 1234560; sr=foobar sr=lumpy,jst")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testWebIDLEditWithProperReviewDuringMergeShouldPass(self):
-    """ Test that editing .webidl file with proper DOM peer review should pass """
-    u = self.ui
-    parentrev = short(self.clonerepo.changectx('tip').node())
-    editFile(join(self.clonedir, "original.webidl"), "interface Foo{};", "interface Bar{};")
-    commit(u, self.clonerepo, message="checkin 1 bug 12345; r=foobar,jst")
-    update(u, self.clonerepo, rev=parentrev)
-    editFile(join(self.clonedir, "dummy"), "foo", "bar")
-    commit(u, self.clonerepo, message="dummy")
-    merge(u, self.clonerepo)
-    commit(u, self.clonerepo, message="merge")
-    result = push(u, self.clonerepo, dest=self.repodir)
-    self.assertEqual(result, 0)
-
-  def testWebIDLEditsInBackoutsWithoutProperReviewShouldPass(self):
-    """ Test that editing .webidl file without proper DOM peer review in backouts should pass """
-    u = self.ui
-    # Copied from testBackout above.
-    messages = [
-      "Backed out changeset 593d94e9492e",
-      "Backout changesets 9e4ab3907b29, 3abc0dbbf710 due to m-oth permaorange",
-      "Backout of 35a679df430b due to bustage",
-      "backout 68941:5b8ade677818", # including the local numeric ID is silly but harmless
-      # we do not have a lot of reverts "hg log | grep revert" without a bug #
-      "Revert to changeset a87ee7550f6a due to incomplete backout",
-      "Backed out 7 changesets (bug 824717) for bustage."
-    ]
-    for message in messages:
-      name = "new%d.webidl" % len(message)
-      appendFile(join(self.clonedir, name), "interface Test{};")
-      add(u, self.clonerepo, join(self.clonedir, name))
-      commit(u, self.clonerepo, message=message)
-      result = push(u, self.clonerepo, dest=self.repodir)
-      self.assertEqual(result, 0)
-
-if __name__ == '__main__':
-  unittest.main()
deleted file mode 100644
--- a/setup.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# This is a distutils setup script for the mozhghooks module.
-# Install the module by running `python setup.py install`
-
-from distutils.core import setup
-
-setup(name="Mozilla Hg Hooks",
-      version='0.1',
-      description="Mozilla-specific hooks for Mercurial VCS",
-      author="Ted Mielczarek",
-      author_email="ted.mielczarek@gmail.com",
-      packages=["mozhghooks"]
-)
deleted file mode 100755
--- a/tamarin-hook.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#! /usr/bin/python
-#  ***** BEGIN LICENSE BLOCK *****
-#  Version: MPL 1.1/GPL 2.0/LGPL 2.1
-# 
-#  The contents of this file are subject to the Mozilla Public License Version
-#  1.1 (the "License"); you may not use this file except in compliance with
-#  the License. You may obtain a copy of the License at
-#  http://www.mozilla.org/MPL/
-# 
-#  Software distributed under the License is distributed on an "AS IS" basis,
-#  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-#  for the specific language governing rights and limitations under the
-#  License.
-# 
-#  The Original Code is [Open Source Virtual Machine.].
-# 
-#  The Initial Developer of the Original Code is
-#  Adobe System Incorporated.
-#  Portions created by the Initial Developer are Copyright (C) 2010
-#  the Initial Developer. All Rights Reserved.
-# 
-#  Contributor(s):
-#    Adobe AS3 Team
-# 
-#  Alternatively, the contents of this file may be used under the terms of
-#  either the GNU General Public License Version 2 or later (the "GPL"), or
-#  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-#  in which case the provisions of the GPL or the LGPL are applicable instead
-#  of those above. If you wish to allow use of your version of this file only
-#  under the terms of either the GPL or the LGPL, and not to allow others to
-#  use your version of this file under the terms of the MPL, indicate your
-#  decision by deleting the provisions above and replace them with the notice
-#  and other provisions required by the GPL or the LGPL. If you do not delete
-#  the provisions above, a recipient may use your version of this file under
-#  the terms of any one of the MPL, the GPL or the LGPL.
-# 
-#  ***** END LICENSE BLOCK ****
-#
-#  Hook script used by tamarin team on tamarin-redux and tamarin-central.
-#
-# For documentation on hook scripts see:
-#   http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html
-#   http://mercurial.selenic.com/wiki/MercurialApi
-
-
-import sys, re
-from mercurial import hg, ui, commands, node
-
-
-# _quiet function from hghooklib by Johann Duscher
-# http://code.google.com/p/hghooklib/
-def _quiet(ui, fn):
-    oldQuiet = ui.quiet
-    ui.quiet = True
-    result = fn()
-    ui.quiet = oldQuiet
-    return result
-
-def master_hook(ui, repo, **kwargs):
-    ui.debug('running tamarin master_hook\n')
-    ui.debug('kwargs: %s\n' % kwargs)
-    # The mercurial hook script expects the equivalent of an exit code back from
-    # this call:
-    #   False = 0 = No Error : allow push
-    #   True = 1 = Error : abort push
-    error = False
-    error = security_check(ui, repo, **kwargs) or error
-    return error
-
-def security_check(ui, repo, **kwargs):
-    ui.debug('running security_check\n')
-    error = False
-    
-    ui.pushbuffer()
-    _quiet(ui, lambda: commands.log(ui, repo, rev=['%s:tip' % kwargs['node']],
-                                    template='{node}\n', date=None, user=None,
-                                    logfile=None))
-    nodes = ui.popbuffer().split('\n')
-    
-    # reenable this code if we need to blacklist a node
-    for node in nodes:
-        if node.startswith('8555e8551203') or node.startswith('e09bb3ece6c7'):
-            ui.warn('blacklisted changeid found: node %s is blacklisted\n' % node)
-            error = True   # fail the push
-    
-    # Look for blacklisted bugs
-    blacklist = [
-        # Serrano
-        580489, 604354,
-        # Wasabi
-        507624,
-        # Cyril
-        570049, 628834,
-        ]
-    
-    bugs = re.compile('(%s)' % '|'.join([str(bug) for bug in blacklist]))
-    
-    ui.pushbuffer()
-    _quiet(ui, lambda: commands.log(ui, repo, rev=['%s:tip' % kwargs['node']],
-                                    template='{desc}', date=None, user=None,
-                                    logfile=None))
-    descs = ui.popbuffer()
-    
-    searchDescs = bugs.search(descs)
-    if searchDescs:
-        ui.warn('blacklisted bug found: %s\n' % searchDescs.groups()[0])
-        error = True
-    
-    return error
\ No newline at end of file
deleted file mode 100755
--- a/test-convert.sh
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/bin/sh
-# This script tests the pushlog converter script. I've only run it on OS X, so be warned.
-
-SCRIPTDIR=`dirname $0`
-
-rm -rf /tmp/hghooks
-# pull an older revision so we can test using the older hooks and converting
-hg clone -r 6209a348c992 http://hg.mozilla.org/users/bsmedberg_mozilla.com/index.cgi/hghooks/ /tmp/hghooks
-
-# need the record script in PATH
-export PATH=$PATH:/tmp/hghooks
-
-REPO=/tmp/hg-test
-CLONE=${REPO}-clone
-# cleanup any existing stuff
-rm -rf $REPO $CLONE
-
-# create a new hg repo
-mkdir $REPO
-hg init $REPO
-
-# setup the old flatfile pushlog hook
-cat > $REPO/.hg/hgrc <<EOF
-[hooks]
-pretxnchangegroup.z_linearhistory = hg_record_changeset_info
-EOF
-
-# now clone it, then commit and push some things
-hg clone $REPO $CLONE
-
-# push two changes together first
-echo "checkin 1" > $CLONE/testfile
-hg add -R $CLONE $CLONE/testfile
-hg ci -R $CLONE -m "checkin 1"
-
-echo "checkin 2" >> $CLONE/testfile
-hg ci -R $CLONE -m "checkin 2"
-hg push -R $CLONE $REPO
-
-# then one separately
-echo "checkin 3" >> $CLONE/testfile
-hg ci -R $CLONE -m "checkin 3"
-hg push -R $CLONE $REPO
-
-# then two together
-echo "checkin 4" >> $CLONE/testfile
-hg ci -R $CLONE -m "checkin 4"
-
-echo "checkin 5" >> $CLONE/testfile
-hg ci -R $CLONE -m "checkin 5"
-hg push -R $CLONE $REPO
-
-# now switch to the previous python+sqlite hook, and run the old convert script
-export PYTHONPATH=/tmp/hghooks
-
-cat > $REPO/.hg/hgrc <<EOF
-[hooks]
-pretxnchangegroup.z_linearhistory = python:mozhghooks.pushlog.log
-EOF
-
-python /tmp/hghooks/convert-pushlog-db.py $REPO/.hg/pushlog || ( echo "FAIL: failed to convert flat-file -> sqlite" && exit 1 ) || exit 1
-
-# Now push a few more things
-# two together, first
-echo "checkin 6" >> $CLONE/testfile
-hg ci -R $CLONE -m "checkin 6"
-
-echo "checkin 7" >> $CLONE/testfile
-hg ci -R $CLONE -m "checkin 7"
-hg push -R $CLONE $REPO
-
-# then one separately
-echo "checkin 8" >> $CLONE/testfile
-hg ci -R $CLONE -m "checkin 8"
-hg push -R $CLONE $REPO
-
-# finally two more together
-echo "checkin 9" >> $CLONE/testfile
-hg ci -R $CLONE -m "checkin 9"
-
-echo "checkin 10" >> $CLONE/testfile
-hg ci -R $CLONE -m "checkin 10"
-hg push -R $CLONE $REPO
-
-# now run the newer convert script
-python $SCRIPTDIR/convert-pushlog-db.py $REPO || ( echo "FAIL: failed to convert pushlog.db -> pushlog2.db" && exit 1 ) || exit 1
-
-# Test total push count
-PUSHCOUNT=`echo "SELECT COUNT(*) FROM pushlog;" | sqlite3 $REPO/.hg/pushlog2.db`
-if [[ "$PUSHCOUNT" != "6" ]]; then
-    echo "FAIL: push count $PUSHCOUNT != 6";
-    exit 1;
-else
-    echo "PASS: push count correct";
-fi
-
-# Test stored changesets
-hg log -R $REPO --template="{node}\n" > /tmp/hg-log-output
-echo "SELECT node from changesets LEFT JOIN pushlog ON pushlog.id = changesets.pushid ORDER BY pushid DESC, rev DESC;" | sqlite3 $REPO/.hg/pushlog2.db > /tmp/pushlog-output
-
-if diff /tmp/hg-log-output /tmp/pushlog-output >/dev/null; then
-    echo "PASS: recorded and converted all changesets";
-else
-    echo "FAIL: hg log and pushlog changesets differ!";
-    exit 1;
-fi
-
-echo "Passed all tests!"