Mercurial预推钩扫描工作副本

时间:2012-02-16 09:31:42

标签: mercurial mercurial-hook

我需要在人们可以推送的存储库上设置一个钩子,这将运行一些验证(目标是在验证失败时拒绝推送)。我已经有一些钩子设置成功推送后自动更新,并防止多个头。

我编写验证脚本没有问题(例如运行单元测试的shell脚本),但它需要在完整的工作副本上运行。

我的问题是,如果我只是将它放在pretxnchangegroup挂钩中,它就不会对更新的文件进行操作。如果我尝试在钩子内部进行hg更新,那么只要验证失败并且推送被回滚,就会导致存储库损坏。

我目前的解决方案是将存储库克隆到某个临时文件夹并在那里运行实际验证。但是我发现这有点难看,并且就地验证只做更新的效率较低。是否可以设置这种钩子?

1 个答案:

答案 0 :(得分:3)

有办法做到这一点,但在我开始之前,你确定要这样做吗?在钩子中进行阻塞,可能 - 缓慢,推迟拒绝的更改会让人感到厌烦,并且它始终保存存储库writelock,因此在验证脚本运行时没有其他人可以推送。人们可以很容易地将DVCS的一半生产力优势抛到窗外,试图获得一点控制。

使用双层存储库设置可以避免大多数这些缺点。像project-push这样的人可以推送w / o传递验证,project-pull只有变更集通过了一些验证。然后你有一个带外(cron或hook触发)脚本,只有在确认验证后才能将变更集从project-push移动到project-pull。因为该测试是在带外推送完成的,所以不会阻止,但是非验证的更改集永远不会进入project-pull。当他们将project-pull推入非验证状态时,您可以通过电子邮件向作者发送电子邮件。像.hg/hgrc这样配置的用户根本不必考虑他们是两个存储库:

[paths]
default=http://host//path/to/project-pull
default-push=http://host//path/to/project-push

他们可以使用hg pushhg pull,事情会“正常”。

如果您的验证不需要同时访问所有更新的文件,那么您可以在外部pretxnchangegroup挂钩中使用类似的内容进行测试:

for thefile in $(hg manifest -r tip) ; do
  if ! hg cat -r tip $thefile | ./validate_on_file.sh ; then
     exit
  fi
done

如果你确实需要一次操作所有文件(编译等)并且你不愿意做一个让人们快速推送的双回购结构,那么你需要一个单独的回购用于测试,但您不必每次都克隆/创建它。在pretxnchangegroup钩子中应该这样做:

hg push /scratch/long-lived-testrepo ## Warning: may not work,  
                                     ## if pretxnchangegroup locks the repo and  
                                     ## blocks this push to testrepo
hg -R /scratch/long-lived-testrepo update
cd /scratch/long-lived-testrepo
./validation.sh