New local pre-commit hook in monotone
July 19, 2010 – 18:13There was only one hook in monotone until now which could be “reused” to interact with the commit process and validate the changeset that should be committed, the validate_commit_message hook. But this was a bit clumsy as it was actually designed to validate the commit message (as the name suggests) and not the changeset, thus the hook was called after the commit message was entered in the editor (or was given with --message or --message-file).
Now monotone (from 0.99 onwards) gained a new commit hook which is called before the commit message processing takes place, but after the logic validated the changeset and branch to which it should be committed. Its named simply validate_changes and takes two parameters, the revision to be committed as full text (parsable in the hook via parse_basic_io) as the first and the name of the branch to which the revision should be committed as the second. Just as validate_commit_message, it is expected to return a tupel containing a boolean which denotes if the change is valid or not and an optional string which explains the reason if not and which is displayed to the committer afterwards.
With this new installment, it should feel natural e.g. to create a pre-commit hook which ensures that none of the patched or added sources contains Windows line endings:
function validate_changes(revdata, branchname)
local parsed = parse_basic_io(revdata)
for _,stanza in ipairs(parsed) do
if stanza.name == "add_file" or
stanza.name == "patch" then
local file = stanza.values[1]
if not guess_binary_file_contents(file) then
local fp = assert(io.open(file, "r"))
local contents = fp:read("*all")
fp:close()
if string.find(contents, "\r\n") then
return false, "CRLF detected"
end
end
end
end
return true, ""
end
Unfortunately its not yet possible to call mtn_automate, the lua interface to monotone’s automation commands, from hooks like this. Then we could have saved the read("*all") call and would only have to scan the output of automate content_diff, which should be a little faster than doing a full string search in lua for bigger files. We, i.e. the monotone devs, are aware of the problem though and will come up with a solution sooner or later.
I hope this new hook will still be useful for some of you until then.


