Home

Headcount

Headcount is a Mercurial hook for restricting intake of unseen changesets over push. Originally it was designed to prevent push of multiple heads, but now it can restrict based on any revset specification. The head count limit is now simply a use case.

Headcount is configured as a pretxnchangegroup hook, meaning that it executes once after a group of changesets is received into a repository (by push, pull, unbundle, serve), but before the changegroup is accepted permanently. This allows headcount to decide whether a changegroup is permissible.

Headcount refuses changegroups in which the number of changesets matching some revset description exceeds a defined limit. Exceptions can be made for the person pushing the changegroup, or based upon the person who committed the changeset(s) in question. (Watch for security gaps here: anyone can falsify their committer name, so be sure your configuration matches your trust profile.)

The original use case is for preventing the push of multiple heads. Mercurial naturally resists pushes of multiple heads, but this can be overcome with 'hg push --force'. Headcount (in the first example configuration below) allows a repository owner to enforce the restriction.

Configuration

There are two general approaches to enabling the extension:

    [hooks]
    pretxnchangegroup.headcount = python:headcount.headcount.hook

or

    [hooks]
    pretxnchangegroup.headcount = python:/path/to/headcount/headcount.py:hook

Configuring headcount policies is straightforward:

    [headcount]
    # If debug is True and source is 'serve' (i.e. pushing over hgweb),
    # transform debug messages to status messages so that they appear
    # remotely.  (ui.debug and ui.note are eaten over http.)
    debug = False
    
    # This creates a policy named 'heads' which biases against bundles
    # in which more than 1 changeset is an unclosed head.
    heads.policy = head() and not closed()
    heads.limit = 1
    
    # If the local username of the user performing the push is in
    # this list, policy violations are allowed.
    # To allow all users to push:
    # push_ok = *
    heads.pushok = user1, user2, user3
    
    # If the author name of a changeset matches[*] one of these names,
    # then that changeset is exempted from the policy.
    # To allow all committers:
    # commit_ok = *
    heads.commitok = userA, User B, userc@example.com
    
    # Template for the error message returned to the Mercurial client.
    # (This is the default message.)
    heads.warnmsg = %(matches)d new heads detected. You may not push new heads to this repository.
    
    # Create a secondary policy preventing pushes to the 'stable' branch,
    # unless the person pushing is identified as 'repoboss'.
    stable.policy = branch(stable)
    stable.limit = 0
    stable.pushok = repoboss
    stable.warnmsg = You may not push to the stable branch.
    

For pushok identifiers, a match is defined as an exact match of the local username provided by mercurial or hgweb. This may be a local account name or the value of REMOTE_USER, etc.

For commitok identifiers, a match is performed against the changeset's "user" string, and may be any of the following: 1. The exact user string; 2. The user@domain address, if the user string parses by rfc822 rules; 3. The user field of the address, if the user string parses by rfc822 rules.

Installation

To install, clone this repository within your Python path (for example, your site-packages directory):

    cd /usr/lib/python2.6/site-packages
    hg clone http://bitbucket.org/dgc/headcount/

Then add to your hgrc file:

    [hooks]
    pretxnchangecount.headcount = python:headcount.headcount.hook

Updated

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.