如何在HG / Mercurial中设置一个由存储库决定的钩子?

时间:2011-09-18 14:34:22

标签: mercurial hgrc mercurial-hook

我需要在更新后运行一个钩子(这将构建他们已经更新的解决方案)并且我不想为每个克隆我的中央存储库的人手动添加该钩子。

当有人第一次克隆我的中央存储库时,是否可以在该克隆中包含挂钩?似乎.hgrc文件不会自动克隆。

我确实阅读过关于网站范围内的钩子,但据我所知,它们可以在每个创建的存储库上工作,我只想在某个存储库中使用钩子。

4 个答案:

答案 0 :(得分:10)

作为Rudi already said,出于安全原因(谢天谢地),这是不可能的。

但是,您可以减少每克隆工作负载以手动设置挂钩:将挂钩脚本作为存储库的一部分发送,例如:在目录.hghooks中,还在repo中包含一个脚本,用于在克隆的hgrc中设置这些钩子。每个同事现在只需要为每个克隆调用一次安装脚本。

答案 1 :(得分:4)

这是不可能的,因为挂钩不会传播到克隆是一种安全措施。如果可以的话,可以设置一个rouge存储库,它在克隆repo的任何机器上运行任意命令。

有关详细信息,请参阅http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html#id402330

答案 2 :(得分:3)

这将允许集中的每个repo挂钩,每个用户只需一个设置步骤。但是,它会给与网络断开连接的用户带来问题。如果您倾向于断开连接的开发人员(或者高延迟/低带宽链路上的开发人员)的另一种选择是拥有包含钩子的repo,并将每个用户的全局hgrc设置为指向该repo(并且需要定期从中央钩子回购)。

请注意,我将第一次提交的ID视为“repo ID” - 这假设每个存储库中的第一次提交在某种程度上是唯一的 - 内容或提交消息。如果不是这种情况你可以做同样的事情,但是在前N次提交中应用它 - 但是你必须考虑少于N次提交的repos - 不能仅仅以repo[:5]为例然后,较新的提交将更改repo ID。我个人建议第一次提交应该是一个标准的.ignore文件,其中包含该repo独有的提交消息。

  1. 拥有一个可从网络共享(或钩子仓库)访问的中央shared_hgrc文件。

  2. 每个用户的全球hgrc都有:

    %include /path/to/shared_hgrc
    
  3. 创建python hook模块的共享存储库。钩子必须用python编写。

  4. 创建钩子函数。在每个函数中,通过检查第一次提交的ID来检查已调用挂钩的repo:

    # hooktest.py
    
    import mercurial.util
    
    FOOBAR_REPO = 'b88c69276866d73310be679b6a4b40d875e26d84'
    
    ALLOW_PRECOMMIT_REPOS = set((
        FOOBAR_REPO,
    ))
    
    def precommit_deny_if_wrong_repo(ui, repo, **kwargs):
        """Aborts if the repo is not allowed to do this.
        The repo ID is the ID of the first commit to the repo."""
    
        repo_id = repo[0].hex().lower()
    
        if repo_id not in ALLOW_PRECOMMIT_REPOS:
            raise mercurial.util.Abort('Repository denied: %s' % (repo_id,))
    
        ui.status('Repository allowed: %s\n' % (repo_id,))
    
    def precommit_skip_if_wrong_repo(ui, repo, **kwargs):
        """Skips the hook if the repo is not allowed to do this.
        The repo ID is the ID of the first commit to the repo."""
    
        repo_id = repo[0].hex().lower()
    
        if repo_id not in ALLOW_PRECOMMIT_REPOS:
            ui.debug('Repository hook skipped: %s\n' % (repo_id,))
            return
    
        ui.status('Repository hook allowed: %s\n' % (repo_id,))
    
  5. 在shared_hgrc文件中,设置您需要的钩子(确保您限定钩子名称以防止冲突):

    [hooks]
    pre-commit.00_skip = python:/path/to/hooktest.py:precommit_skip_if_wrong_repo
    pre-commit.01_deny = python:/path/to/hooktest.py:precommit_deny_if_wrong_repo
    

答案 3 :(得分:1)

正如@Rudi首先说的那样,出于安全原因不能这样做。

通过一些先前的设置,您可以使钩子在克隆上运行,但在/etc/mercurial或每个用户的~/.hgrc中放置一个具有repo-relative路径的钩子,这在公司设置中可以通过您的系统管理工具或构建自定义Mercurial安装程序来完成。在非公司环境中,请遵循@ Oben的建议并提供脚本和自述文件。