Online Book Reader

Home Category

Mercurial_ The Definitive Guide - Bryan O'Sullivan [72]

By Root 946 0
did not install yourself. If you work with Mercurial on an unfamiliar system, Mercurial will run hooks defined in that system’s global ~/.hgrc file.

If you are working with a repository owned by another user, Mercurial can run hooks defined in that user’s repository, but it will still run them as “you.” For example, if you hg pull from that repository, and its .hg/hgrc defines a local outgoing hook, that hook will run under your user account, even though you don’t own that repository.

* * *

Note


This only applies if you are pulling from a repository on a local or network filesystem. If you’re pulling over http or ssh, any outgoing hook will run under whatever account is executing the server process on the server.

* * *

To see what hooks are defined in a repository, use the hg showconfig hooks command. If you are working in one repository but talking to another that you do not own (e.g., using hg pull or hg incoming), remember that it is the other repository’s hooks you should be checking, not your own.

Hooks Do Not Propagate

In Mercurial, hooks are not revision controlled, and do not propagate when you clone, or pull from, a repository. The reason for this is simple: a hook is a completely arbitrary piece of executable code. It runs under your user identity, with your privilege level, on your machine.

It would be extremely reckless for any distributed revision control system to implement revision-controlled hooks, as this would offer an easily exploitable way to subvert the accounts of users of the revision control system.

Since Mercurial does not propagate hooks, if you are collaborating with other people on a common project, you should not assume that they are using the same Mercurial hooks as you are, or that theirs are correctly configured. You should document the hooks you expect people to use.

In a corporate intranet, this is somewhat easier to control, as you can for example provide a “standard” installation of Mercurial on an NFS filesystem, and use a site-wide ~/.hgrc file to define hooks that all users will see. However, this too has its limits; see below.

Hooks Can Be Overridden

Mercurial allows you to override a hook definition by redefining the hook. You can disable it by setting its value to the empty string, or change its behavior as you wish.

If you deploy a system- or site-wide ~/.hgrc file that defines some hooks, you should thus understand that your users can disable or override those hooks.

Ensuring That Critical Hooks Are Run

Sometimes you may want to enforce a policy that you do not want others to be able to work around. For example, you may have a requirement that every changeset must pass a rigorous set of tests. Defining this requirement via a hook in a site-wide ~/.hgrc won’t work for remote users on laptops, and of course local users can subvert it at will by overriding the hook.

Instead, you can set up your policies for use of Mercurial so that people are expected to propagate changes through a well-known “canonical” server that you have locked down and configured appropriately.

One way to do this is via a combination of social engineering and technology. Set up a restricted-access account; users can push changes over the network to repositories managed by this account, but they cannot log into the account and run normal shell commands. In this scenario, a user can commit a changeset that contains any old garbage they want.

When someone pushes a changeset to the server that everyone pulls from, the server will test the changeset before it accepts it as permanent, and reject it if it fails to pass the test suite. If people only pull changes from this filtering server, it will serve to ensure that all changes that people pull have been automatically vetted.

A Short Tutorial on Using Hooks

It is easy to write a Mercurial hook. Let’s start with a hook that runs when you finish a hg commit, and simply prints the hash of the changeset you just created. The hook is called commit.

All hooks follow the pattern in this example.

$ hg init

Return Main Page Previous Page Next Page

®Online Book Reader