1

Sometimes developers on my team forget to pull in other developer's changesets before committing their own (admittedly, I do this as well). For a week long project there could be dozens of changes in the tree that the new commit skips over. When trying to push, hg aborts with the new remote head message then they pull and merge in all those new commits. What I'm looking for is an easy way to test if there are any new changes before someone commits and if there are to prevent the commit from happening. Ideally, there would be a clear message stating why the commit failed.

This seems like it should be very easy for a hook to accomplish but the pre-commit hook will continue on a status code of 0 and hg incoming will return 1 when there are no changes. All I need to do is invert the status of the hg incoming command but I can't find the syntax to do it. Most of the search results that I've found dive right into writing python hooks but that seems like overkill for such a simple problem.

I'm looking for something like this:

[hooks]
pre-commit != hg incoming
or
pre-commit = hg incoming == 0

I'm not sure where the message would go, either.

NeilAE
  • 11
  • 2
  • A python script may not be so overkill if you need the message, too! – Vince Aug 07 '14 at 16:33
  • @Vince: I don't _need_ a message, it just would be ideal. I think my frustration was due to not being able to apply a simple logic NOT to the result of an Hg command. – NeilAE Aug 07 '14 at 17:47
  • blocking *any local* operations in case of *some remote* state is **BAD IDEA (tm)**. Anyway, you can try to redefine `hg commit` with shell-alias – Lazy Badger Aug 07 '14 at 19:52

3 Answers3

3

On Windows you can use this command to check for incoming changes:

[hooks]
pre-commit.checkNew = CMD /V /C "hg incoming & IF !ErrorLevel! EQU 0 (Exit 1) Else (Exit 0)"

If new changes are found it will cancel the commit and you will need to pull (and possibly merge) the new changes.

stomtech
  • 454
  • 4
  • 10
1

You had it mostly right, but you got the hook wrong:

[hooks]
precommit = ! hg incoming

There's no dash in the hook that can cancel the commit.

If, however, you turn a DVCS system into something where people can't commit without being connected to the internet your coworkers will string you up. :)

Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
  • thanks @Ry4an. We use bitbucket and it does become inaccessible at times, however, this will be a local hook that the developer can easily remove. It's really just a reminder to prevent the 'oops, I forgot to pull first' scenario. – NeilAE Aug 08 '14 at 12:40
  • That hook still does not work for me. I get "abort: precommit hook exited with status 1 [Code: 255]"(from tortoiseHg). From the command line I get `'!' is not recognized as an internal or external command, operable program or batch file. abort: precommit hook exited with status 1` – NeilAE Aug 08 '14 at 12:49
  • Ah! You're on windows! `!` is part of the unix shell. It negates the exit code of any command. `! true ; echo $?` prints `1` (because 1 is false in exitcode land) – Ry4an Brase Aug 08 '14 at 17:56
0

I found a solution by rereading the docs again: control if hook can proceed. Where I found the grep command in use.

[hooks]
precommit.comment = REM Don't forget to pull first!
precommit.test = hg incoming | grep -q "no changes found"

When a developer gets a failed commit they can check the output log and see the note. Not too pretty but should suffice most of the time. -q prevents "no changes found" from appearing in the log which would be confusing after a failed commit. I added my own extensions .comment and .test so the hooks get run in the correct order (c before t).

NeilAE
  • 11
  • 2