Online Book Reader

Home Category

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

By Root 961 0
object; at the moment, it is always an instance of localrepository. Following these two arguments are other keyword arguments. Which ones are passed in depends on the hook being called, but a hook can ignore arguments it doesn’t care about by dropping them into a keyword argument dict, as with **kwargs above.

Some Hook Examples

Writing Meaningful Commit Messages

It’s hard to imagine a useful commit message being very short. The simple pretxncommit hook of the example below will prevent you from committing a changeset with a message that is less than ten bytes long.

$ cat .hg/hgrc

[hooks]

pretxncommit.msglen = test `hg tip --template {desc} | wc -c` -ge 10

$ echo a > a

$ hg add a

$ hg commit -A -m 'too short'

transaction abort!

rollback completed

abort: pretxncommit.msglen hook exited with status 1

$ hg commit -A -m 'long enough'

Checking for Trailing Whitespace

An interesting use of a commit-related hook is to help you to write cleaner code. A simple example of “cleaner code” is the dictum that a change should not add any new lines of text that contain “trailing whitespace.” Trailing whitespace is a series of space and tab characters at the end of a line of text. In most cases, trailing whitespace is unnecessary, invisible noise, but it is occasionally problematic, and people often prefer to get rid of it.

You can use either the precommit or pretxncommit hook to tell whether you have a trailing whitespace problem. If you use the precommit hook, the hook will not know which files you are committing, so it will have to check every modified file in the repository for trailing white space. If you want to commit a change to just the file foo, but the file bar contains trailing whitespace, doing a check in the precommit hook will prevent you from committing foo due to the problem with bar. This doesn’t seem right.

Should you choose the pretxncommit hook, the check won’t occur until just before the transaction for the commit completes. This will allow you to check for problems only in the exact files that are being committed. However, if you entered the commit message interactively and the hook fails, the transaction will roll back; you’ll have to re-enter the commit message after you fix the trailing whitespace and run hg commit again.

$ cat .hg/hgrc

[hooks]

pretxncommit.whitespace = hg export tip | (! egrep -q '^\+.*[ \t]$')

$ echo 'a ' > a

$ hg commit -A -m 'test with trailing whitespace'

adding a

transaction abort!

rollback completed

abort: pretxncommit.whitespace hook exited with status 1

$ echo 'a' > a

$ hg commit -A -m 'drop trailing whitespace and try again'

In this example, we introduce a simple pretxncommit hook that checks for trailing whitespace. This hook is short, but not very helpful. It exits with an error status if a change adds a line with trailing whitespace to any file, but does not print any information that might help us to identify the offending file or line. It also has the nice property of not paying attention to unmodified lines; only lines that introduce new trailing whitespace cause problems.

#!/usr/bin/env python

#

# save as .hg/check_whitespace.py and make executable

import re

def trailing_whitespace(difflines):

#

linenum, header = 0, False

for line in difflines:

if header:

# remember the name of the file that this diff affects

m = re.match(r'(?:---|\+\+\+) ([^\t]+)', line)

if m and m.group(1) != '/dev/null':

filename = m.group(1).split('/', 1)[-1]

if line.startswith('+++ '):

header = False

continue

if line.startswith('diff '):

header = True

continue

# hunk header - save the line number

m = re.match(r'@@ -\d+,\d+ \+(\d+),', line)

if m:

linenum = int(m.group(1))

continue

# hunk body - check for an added line with trailing whitespace

m = re.match(r'\+.*\s$', line)

if m:

yield filename, linenum

if line and line[0] in ' +':

linenum += 1

if __name__ == '__main__':

import os, sys

added = 0

for filename, linenum in trailing_whitespace(os.popen('hg export tip')):

print >> sys.stderr, ('%s, line %d: trailing whitespace

Return Main Page Previous Page Next Page

®Online Book Reader