Mercurial pre commit hook - stop commit based on file contents?
Asked Answered
S

3

19

How can I setup a pre-commit hook , that will search for a string in the committed files and If found stop the commit ?

Schoolboy answered 12/11, 2010 at 7:12 Comment(3)
It seems to me that it would go against concept of decentralized repository. Your repository may be cloned to another machines with different systems, and your script may simply not work there. Maybe pre-push hook would be better? I'm interested to hear answer to your question.Mistrustful
I have a central repository where people are pushing. I just need to make sure the commits I made are clean before I push them.Schoolboy
Try to check selenic.com/mercurial/hgrc.5.html#hooksMistrustful
L
26

Chapter 10 of the mercurial book covers this exactly:

$ 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.

Just change the regular expression from '^\+.*[ \t]$' to whatever string you're looking for.

Leyva answered 12/11, 2010 at 17:13 Comment(6)
OK, ofcourse I found that example by now but how does it work ? why do I need -> hg export tip and what is this returning (! egrep -q '^\+.*[ \t]$') ?Schoolboy
FYI, this won't work if you don't add a tag with every commit (i.e. via -A)Gerena
this is a terrible example for most developers: uses a shell script and egrep. developers in most working environments are uncomfortable with this stuff - to a very good approximation nobody uses it - further there is no explanation or way to determine e.g. what parameters are/are not passed into the hook from this example...Ruble
Sorry it's not your cup of tea @jheriko. If you add an answer that works on all platforms I'm happy to up vote it. I've worked the last 20 year in high-unix-competency environments and it definitely colors what I consider easy.Leyva
i think the xplatform solution would be to use python unfortunately which is another layer of confusion of a different kind... there are plenty of examples in the mercurial docs and this question is old and the answer accepted now so i won't bother. i generally have a bee in my bonnet about *nix/bash style tools/scripts in general...Ruble
shrug bash is available on all the same platforms as python and neither comes pre-installed on Windows, but it's an one liner in either language.Leyva
C
5

Ry4an's answer is almost correct :) but you need to replace "hg export tip" with "hg diff".
tip is the last commited changeset, but are interested in local uncommited changes - so diff is what u need. for my needs i added the following to my hgrc

precommit.removeDebug = hg diff -S | grep -v '^-' | (! egrep '(var_dump)|(exit)|(print_r)')

the -S includes subrepos (maye not need, and may be still buggy).
the grep -v '^-' removes lines from the diff that indicate lines that were removed. i removed the -q so i at least have a idea what to remove, but unfortunatly this method cannot print you the file and linenumber of the occurence (as it is piped). maybe someone has a better way to do it.

Carmine answered 3/3, 2011 at 9:56 Comment(2)
I stand by my answer. :) The local changes are already committed by the time the pretxncommit book runs -- it's after the work but before the transaction is committed, so hg export tip works fine, and it's rolled back when the hook says no.Leyva
hg export tip works fine, I agree, but, based purely on my own very unscientific observations, hg diff works slightly faster.Jerk
G
5

BTW, on Windows you can use

[hooks]
pretxncommit.nocommit = hg export tip | findstr NOCOMMIT && EXIT /B 1 || EXIT /B 0

This hook will fail if your sources contains string "NOCOMMIT"

Gametophore answered 27/1, 2014 at 15:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.