pretxnchangegroup hook fails because it can't acquire lock

Mick Jordan mick.jordan at oracle.com
Tue Nov 5 06:39:58 CST 2013


On 11/5/13 3:41 AM, Simon King wrote:
> On Tue, Nov 5, 2013 at 9:06 AM, Pierre-Yves David
> <pierre-yves.david at ens-lyon.org> wrote:
>> On 5 nov. 2013, at 03:16, Mick Jordan wrote:
>>
>>> I have a pretxnchangegroup hook on a repo 'x' that runs a python script that, essentially, calls "hg push x-2', where other tests runs to determine whether the changegroup should be accepted. The repo is on a server that is receiving the push via http, using Apache 2.2 and hgweb. All the repo files are group apache and the owner of the files is trusted in the apache user .hgrc file. The system is essentially a Red Hat Linux 6.
>>>
>>> Mercurial is 2.2.2 and running under Python 2.6.6, which is the default installed Python. The hook script is running under python2.7.5, as it needs features from that version.
>>>
>>> First, 'hg outgoing http://x' works fine, so the basic permissions are correct (it too a while to get that far).
>>>
>>> However, the 'hg push http://x'  does not. The "hg push x-2" in the hook hangs waiting for the lock on 'x' and eventually times out. I can see the lock file in 'x/.hg/store' which is a symbolic link to the python process running hgweb.cgi (and hence the hook). Now, almost exactly the same configuration exists on another machine, running slightly different versions of Apache, hg, Linux and python and works flawlessly. So what is the problem on my machine? Does 'push' really need the lock? Is it yet another weird permissions problem?
>>>
>>> I can verify in another shell that I can clone 'x' to, say, 'y', but if I also explicitly attempt to then  'hg push 'y' ', I get the same 'waiting for lock message'.
>>>
>>> Someone who understand the Mercurial locking system please explain why this works on one machine but not another?
>> from mercurial 2.1, hg push lock the repo (because push may change local phases). We made that optional (it push anyway if it fails to lock) in 2.6
>>
> (For reference, the BTS entry for this was
> http://bz.selenic.com/show_bug.cgi?id=3684)
>
> When the inability to lock the repository is caused by permission
> problems, the fix in 2.6 is fine. However, in Mick's case, the problem
> is that the repository is already locked by the parent push process.
> The child push process tries to lock the repository and eventually
> times out, and the parent push is rolled back.
>
> Steps to reproduce:
>
> #------------------------
> hg init src
> hg init dest1
> hg init dest2
>
> cat >dest1/.hg/hgrc <<EOF
> [hooks]
> pretxnchangegroup.push = hg push ../dest2
> EOF
>
> cat >hgrc <<EOF
> [ui]
> timeout=5
> EOF
>
> cd src/
> touch a
> hg ci -Am0
>
> HGRCPATH=$PWD/../hgrc hg push ../dest1/
> #------------------------
>
> Result:
>
> waiting for lock on repository /tmp/simonk/hgtest/dest1 held by 'srv:4187'
> abort: repository /tmp/simonk/hgtest/dest1: timed out waiting for lock
> held by srv:4187
> transaction abort!
> rollback completed
> abort: pretxnchangegroup.push hook exited with status 255
>
>
> I worked around this with an in-process hook to perform the push.
> Because it's in-process, it inherits the parent lock so doesn't have
> this problem:
>
> #------------------------
> import mercurial.commands
>
> # It is no longer possible to run "hg push" in a pretxnchangegroup
> # hook, because pushing requires locking the repository. This is an
> # in-python version of the hook that works around the problem.
> def pushwhilelocked(ui, repo, **kwargs):
>      destnames = ['ontxnchangegroup', 'default-push', 'default']
>      for dest in destnames:
>          path = ui.config('paths', dest, None)
>          if path is not None:
>              break
>      else:
>          raise mercurial.util.Abort('no path to push to')
>
>      return mercurial.commands.push(ui, repo, dest)
> #------------------------
>
> Enable it in the repository with something like:
>
> [hooks]
> pretxnchangegroup.push = python:/path/to/hook/script.py:pushwhilelocked
>
>
I certainly appreciate the explanation and it explains why the other 
system "works" because it is using Mercurial 1.9.1. The problem I see 
with the in-process hook is that it will be running the "wrong" version 
of Python (2.6.6). Is there a way I can install hg to use an alternate 
version of Python. I believe that if I mess with the system version, 
tools like yum will fail, which would be bad.

Mick





More information about the Mercurial mailing list