3

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

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

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

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

4

1 回答 1

3

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

您可以通过两层存储库设置来避免大多数这些缺点。就像project-push人们可以在没有通过验证的情况下推送的地方,并且project-pull只有通过一些验证的变更集。然后,您有一个带外(cron 或钩子触发)脚本,仅在确认验证后才将变更集从 移动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 pushandhg pull并且事情会“正常工作”。

也就是说,如果您的验证不需要同时访问所有更新的文件,您可以在外部pretxnchangegroup挂钩中使用类似这样的东西进行测试:

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

如果您确实需要一次对所有文件进行操作(编译等)并且您不愿意做一个可以让人们快速推送的两个 repo 结构,那么您确实需要一个单独的 repo 进行测试,但是您不必每次都克隆/创建它。像这样的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
于 2012-02-16T14:52:18.377 回答