precommit mercurial hook to stop commits to the wrong branch

Faheem Mitha faheem at faheem.info
Fri Oct 11 19:12:07 UTC 2013


On Fri, 11 Oct 2013, Faheem Mitha wrote:

>
> On Thu, 10 Oct 2013, Faheem Mitha wrote:
>
>> I see there is also http://mercurial.selenic.com/wiki/PythonHglib
>
> I posted the following approach to SO:
>
> http://stackoverflow.com/a/19305079/350713
>
> The post appears below. However, I still have a problem.

> I use mq, and when it comes to mq commits, I don't care what commits
> are made to what branch, because mq itself doesn't really care about
> branches (an mq patch takes the name of whatever branch it is
> qpushed to), and so one can merrily pop and push mq patches between
> branches.

> So, is there some good way to tell the hook that if the commit in
> progress is an mq commit, don't do anything?

> I looked at mq.py for a bit, but didn't see any obvious way to do
> this. As you can see, I am using hglib for my hook, so a solution
> that integrates with hglib would be nice, but if I have to drop down
> to a low level API, then I guess I can live with that.

>                                                           Regards, Faheem
>
> ########################################################################

> Using @Ry4an's solution as a starting point, I came up with the
> following script using the new hglib API.

> #!/usr/bin/python
>
> # Abort commit to the debian branch if it is not contained in a debian
> # subdirectory
>
> # Similary abort commit to non-debian branches if it is contained in a
> # debian subdirectory
>
> import hglib, os, sys
> client = hglib.open("/home/faheem/hooktest")
> ctx = client['tip']
> files = ctx.files()
> branch = ctx.branch()
>
> for f in files:
>    d = os.path.dirname(f)
>    if branch == "debian" and d != "debian":
>        sys.exit("cannot commit %s (file not in 'debian' directory) to
> 'debian' branch"%f)
>    if branch != "debian" and d == "debian":
>        sys.exit("cannot commit %s (file in 'debian' directory) to non
> 'debian' branch"%f)

Here is an in-process hook which allows MQ commits. Thanks to Brendan and
Bob Hood for helpful information. However, I *still* have a problem. I can
convert an MQ commit into a regular commit with qfinish, and the hook
doesn't stop me. Does anyone have any ideas about that?

                                                            Regards, Faheem

##########################################################################

def abort_commit_to_wrong_branch(ui, repo, **kwargs):
     # If repo has '_committingpatch' attribute, then it is an mq
     # commit in progress, so return 'False'
     import os
     ctx = repo[kwargs['node']]
     files = ctx.files()
     branch = ctx.branch()
     if hasattr(repo, "_committingpatch"):
         for f in files:
             d = os.path.dirname(f)
             if branch == "debian" and d != "debian":
                 ui.warn("Warning: committing %s (file not in 'debian' directory) to 'debian' branch. Allowed since this ia an MQ commit.\n"%f)
             if branch != "debian" and d == "debian":
                 ui.warn("Warning: committing %s (file in 'debian' directory) to non 'debian' branch. Allowed since this ia an MQ commit.\n"%f)
         return False
     for f in files:
         d = os.path.dirname(f)
         if branch == "debian" and d != "debian":
             ui.warn("Error: cannot commit %s (file not in 'debian' directory) to 'debian' branch\n"%f)
             return True
         if branch != "debian" and d == "debian":
             ui.warn("Error: cannot commit %s (file in 'debian' directory) to non 'debian' branch\n"%f)
             return True



More information about the Mercurial mailing list