2017-05-17 85 views
0

我们有提交消息规则的鸡与鸡蛋情况。直到之后提交之后才能知道一条信息。我们认为,不要求用户修改提交(如果提交较旧,则需要重新绑定),如果用户只需通过“注释”机制添加信息就会很好。好的,到目前为止,这么好。在git预接收钩子中访问Notes

问题是,如果commit + notes信息不符合规则,我希望'pre-receive'钩子能够失败推送。然而,我似乎无法弄清楚如何查看给定提交的注释,除非笔记已经被提前提交。

我可以简单地允许笔记推送通过未选中,然后检查提交消息和它的笔记,当我看到提交。但是,这是一个不太理想的解决方法。我们可以保证订单先做笔记,然后提交。但是,这是一个黑客。由于笔记中的信息,如果提交+笔记失败,该怎么办?这意味着可以通过的说明需要修改。

相反,我想要同时获得笔记和提交(类似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什么都没有产生。

想法?谢谢。

+0

也许您需要接受临时分支机构,并且只有在所有信息都存在的情况下才可以回扣它们(有点像Gerrit中的提交门) – eckes

回答

1

预收到钩得到所有参考更新(在标准输入),那么你可以通过他们都看过,看是否有refs/notes/更新,通过Notes读取,然后将您的规则对基础笔记对象。然而,这是非常痛苦的:因为(你注意到)refs/notes/参考本身还没有更新,所以git log找不到新的音符,所以你不得不深入到音符的实现中。

作为一种替代方法,您也许可以手动更新挂钩内部的注释参考更新。不过这至少有点危险:在继续之前,你需要“撤消”这个更新(使更新看起来像原子一样)确保没有别的东西使用注释或Git存储库所有,在此期间。 (原因很复杂,并且依赖于Git版本:较新的Gits将传入对象放置在单独的备用对象存储中,使它们可用于预接收和更新挂钩,但通常不可用,因此传入对象不需要丢弃,如果推被拒绝。)

我认为eckes' suggestion (in a comment)也许是要走的路。为了使其更加精细和自动化,您可以使用gitnamespaces,而不是禁止或允许推送到refs/heads/foo,以便所有推送都会以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进行推送。

+0

感谢您的好信息。我们决定修改我们的工作流程,而不是解决这些复杂的问题。 – tanager