在git预接收挂钩中访问Notes

时间:2017-05-17 22:37:29

标签: git

我们有一个带有提交消息规则的鸡与蛋的情况。在之后提交之前,无法知道一条信息。我们认为,如果用户只需通过“注释”添加信息,那么用户就可以修改提交(或者如果提交时间更长,则更改)。机制。好的,到目前为止,非常好。

问题在于我希望“预先接收”'如果提交+注释信息不符合规则,则钩子能够使推送失败。但是,我似乎无法弄清楚如何查看给定提交的注释,除非注释已经在提交之前被推送。

我可以简单地允许注释未经检查,然后在看到提交时检查提交消息及其注释。但是,这是一种不太理想的解决方法。我们可以保证订单首先是备注,然后是第二个。但是,这是一个黑客。如果提交+注释由于注释中的信息而失败怎么办?这意味着需要修改允许通过的注释。

相反,我希望将两个注释和提交放在一起(类似git push origin refs/notes/* refs/heads/<branch>)。我们可以控制它,因为我们的推送使用包装器脚本。如果两次推动一起发生,我应该能够通过/失败整个事情。没有错误的信息通过。

但我不能为我的生活弄清楚如何看到笔记。理想的情况是在推送中的每个提交中使用git log --format=%N -1 <commit>之类的东西。但这并没有产生任何结果,我想因为提交和备注尚未完成。我已经尝试git notes list希望我可以打印哈希指向的对象(git cat-file -p <hash>)。但git notes list也没有产生任何结果。

想法?感谢。

1 个答案:

答案 0 :(得分:1)

预接收挂钩获取所有参考更新(在stdin上),因此您可以全部读取它们,查看是否有refs/notes/次更新,读取注释,以及然后将您的规则应用于基础笔记对象。但这非常痛苦:你必须深入研究笔记的实现,因为(如你所知)refs/notes/引用本身尚未更新,因此git log无法找到新笔记

作为替代方案,您也可以手动更新钩子中的注释引用更新。但这至少有点危险:你想要&#34;撤消&#34;在继续之前进行此更新(使更新看起来像原子一样)确保在此期间没有其他任何内容使用这些注释或Git存储库。 (原因很复杂且依赖于Git版本:较新的Gits将传入的对象放在一个单独的备用对象存储中,使它们可用于预接收和更新挂钩,但一般不可用,因此传入的对象不必是如果推送被拒绝则丢弃。)

我认为eckes' suggestion (in a comment)也许是要走的路。为了使其更加精细和自动,而不是禁止或允许推送到refs/heads/foo,您可以使用gitnamespaces,以便所有推送最终转到refs/proposed/refs/heads/foo(并要求这样做)是这个名字的新创造者)。然后,在接受推送后,运行检查更新的后处理过程。如果它很好,请将其移至refs/heads/foo。如果没有,请删除refs/proposed/refs/heads/foo名称,并发送推送电子邮件的任何人,说他们的推送已自动回滚。这个想法有一个明显的缺点:他们的Git会认为推送已经被接受,他们将不得不重新运行git fetch以使他们的refs/remotes/origin/foo重新设置回未更新的值。另外,技术上很难确切地知道谁做了推送,除非你使用唯一的用户信息(你可以在接受refs/proposed/refs/heads/foo的同时记录)通过ssh发生所有推送。