Hooks provide an interesting way to customize the behavior of Bazaar. Many Bazaar operations are associated with one or more hook points, and by registering a custom method to a hook point, the method is automatically triggered when the associated Bazaar operation is performed. Common examples are the pre-commit and post-commit hook points, which are triggered right before or after a commit operation in a branch, respectively.
A hook point corresponds to an event in a version control operation. You can register a method to a hook point to be called back when the associated event fires. Hook points have the following attributes:
Hook points are created in various parts of bzrlib
. Based on their functionality, hook points can be grouped into hook classes. Hook classes in bzrlib
are derived from the common parent Hooks
class, and each hook class registers a number of hook types. For example, the BranchHooks
class registers hook types such as post_commit
, post_change_branch_tip
, and the MergeHooks
class registers hook types, such as post_merge
. A hook point is identified by a hook class and a hook type registered by that class.
Hook classes keep a registry of the hooks they have registered, called a hook dictionary. In turn, all the hook dictionaries are created by all the hook classes form the global hooks registry within Bazaar. This is important to understand in order to locate the implementation of the hook points listed in bzr help hooks
.
For example, the output of bzr help hooks
shows a hook point MergeHooks/post_merge
, but it is not quite clear where to find the right module name and how to register callbacks to this hook point. To find this piece of information, you can look at the registry of hooks by using the following code snippet:
import bzrlib.hooks for item in bzrlib.hooks.known_hooks.items(): print item
This will print out a tuple for each hook class. For example:
(('bzrlib.branch', 'Branch.hooks'), <class 'bzrlib.branch.BranchHooks'>) (('bzrlib.commands', 'Command.hooks'), <class 'bzrlib.commands.CommandHooks'>) (('bzrlib.config', 'ConfigHooks'), <class 'bzrlib.config._ConfigHooks'>) (('bzrlib.merge', 'Merger.hooks'), <class 'bzrlib.merge.MergeHooks'>) # ... many more
Each item is in the form ((MODULE, NAME), CLASS)
, and it uniquely identifies a hook class and its associated hook dictionary:
This is crucial information when registering hooks.
As already explained when creating a plugin, hooks should be registered in the __init__.py
file of the plugin.
The general form for registering a hook is as follows:
from MODULE import NAME NAME.install_named_hook_lazy(ARGS)
Here, MODULE
and NAME
are as printed by the snippet in the previous section (based on items in bzrlib.hooks.known_hooks
), and ARGS
are as explained earlier when creating plugins. For example:
from bzrlib.branch import Branch Branch.hooks.install_named_hook_lazy( 'post_commit', 'bzrlib.plugins.appendlog.hooks', 'post_commit_hook', 'Append commit statistics to a log file.' )
Registration alone does not necessarily "activate" a hook. For example, although the email plugin registers several callback methods that are triggered by the post_commit
and post_change_branch_tip
hook points, these methods do nothing unless the appropriate configuration variables are present in the branch configuration. Read the documentation of the relevant hook to find out how to really activate it. For example, the appendlog
sample plugin we introduced earlier requires the post_commit_log
configuration value.
An easy way to set values in the branch configuration is by using the bzr config
command. For example:
$ bzr config name=value
To see all the currently set configuration values, simply run bzr config
without any parameters.
52.15.135.175