Git预接收钩子来检查配置 [英] Git pre-receive hook to check config

查看:188
本文介绍了Git预接收钩子来检查配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我们的git服务器中设置一个预接收钩子,它检查一个配置文件,并在推送无效时放弃推送(我想根据分支名称检查某些标记的存在)。但我已经看到,先前的钩子只是收到(old-rev,new-rev,refname)列表,我发现检查文件内容的唯一方法是区分那些引用,这不是很舒适。



有没有简单的方法来做到这一点?
使用precommit钩子会更容易,但我希望在服务器中拥有最后一道屏障。

解决方案

在新对象(提交,注释标记对象,树和blob)已被加载到存储库中之后,但在引用(分支名称,标记名称等)已被更改之前,将调用预接收或更新挂钩。



这就是为什么预接收钩子获取( old c> ref )三元组:现有的回购包含对象和现有的ref(如果有的话)指向其SHA-1为 old 的对象(通常为commit,有时标记) 。 Git建议将它改为指向SHA-1为 new 的对象(或者创建它或删除它,如果这两个对象中的一个是全零空SHA-1)。


我发现检查文件内容的唯一方法是区分那些引用

这是一种方式,但您拥有整套git命令来提取所有内容。例如,您可以在某处( mkdir path )创建一个新的空目录,然后运行 git --work- tree = path checkout sha1 来获取一个完整的树进入该路径。 (如果树很大,这可能需要一些时间,当然,你运行的任何测试都需要更多的时间。)



你必须决定你想检查。这与你想要的一样复杂,但对于分支名称( ref )的形式 refs / heads / em> name ,其中 是任何分支名称,即可能包含更多斜杠),请考虑ref更新可能会执行以下一项或多项操作(某些组合显然是不可能的):


  • 添加一个新的分支名称

  • 向现有分支中添加新提交
  • 从现有分支中删除提交
  • 删除现有分支例如,如果我有一个裸回购的克隆 origin 我做到这一点:

      git fetch origin#获取最新的原始文件
    git checkout -b分支原产地/分行#为原产地/分行做跟踪分行
    git reset --hard HEAD〜3#备份3提交
    回复更多内容>> existing_file#修改某些内容
    git commit -a -m'添加新文本'#提交更改
    git revert --no-edit HEAD#添加另一个提交,撤消更改
    git push -f起源分支#并推送

    ,那么更新将删除三个提交并添加两个。如果您签出了 new SHA-1(同样使用 old ref 三重符号)看起来完全像我要求推送的版本。如果有一些树必须通过的测试,推测大概是 HEAD〜3 的版本确实通过了这些测试,所以这个版本也是如此。然而,我承诺增加一行到 existing_file 可能不会 通过测试,并且您可能不喜欢我移除了三次提交。

    因此,您需要决定要检查的内容,然后编写代码来实现这一点。检查强制推送是否删除提交;允许或禁止这一点。检查是否正在创建新的分支名称;允许或禁止。检查分支名称是否被删除;允许或禁止。如果正在添加提交,请检查每个中间提交的树,或仅检查最终的树;允许或禁止。提交被添加涉及合并?标签被添加,删除或更改了吗?等等。

    为了好玩,前一段时间我写了一篇预接收shell脚本(在POSIX样式的shell中),它执行许多这样的操作(它不检查任何提交的内容)。我做了一些非常轻的测试,它似乎工作。它可以作为更彻底检查的起点。



    然而,如果您正在认真检查,您可能需要使用 gitolite


    Id like to set a pre-receive hook in our git server that checks a config file and discards the push if it's invalid (I want to check presence of certain tokens depending on branch name). But I've seen preceive hook just receives a list of (old-rev, new-rev, refname) and the only way I've found to inspect file contents is diffing those references, which is not very confortable.

    Is there an easy way to do this? With a precommit hook it would be easier but I'd like to have a last barrier in the server.

    解决方案

    A pre-receive or update hook is called after the new objects (commits, annotated tag objects, trees, and blobs) have been loaded into the repository, but before the references (branch names, tag names, etc) have been changed.

    This is why the pre-receive hook gets a list of (old, new, ref) triples: the existing repo has the objects and the existing ref (if any) points to the object (usually commit, sometimes tag) whose SHA-1 is old. Git is proposing to change it to point to the object whose SHA-1 is new (or create it or delete it if exactly one of those two is the all-zeros "null SHA-1").

    the only way I've found to inspect file contents is diffing those references

    That's one way, but you have the entire suite of git commands to extract everything. You can, for instance, make a new, empty directory somewhere (mkdir path) and run git --work-tree=path checkout sha1 to get a complete tree into that path. (If the tree is large this could take some time. Of course any tests you run on it will take even more time.)

    You must decide what, precisely, you want to check. This is as complicated as you want it to be, but for branch names (a ref of the form refs/heads/name, where name is any branch name, i.e., may contain more slashes), consider that the ref update may do one or more of the following (some combinations are obviously impossible):

    • Add a new branch name
    • Add new commits to an existing branch
    • Remove commits from an existing branch
    • Remove an existing branch name

    For instance, if I have a clone of a bare repo origin and I do this:

    git fetch origin                      # get up-to-date with origin
    git checkout -b branch origin/branch  # make tracking branch for origin/branch
    git reset --hard HEAD~3               # back up 3 commits
    echo more stuff >> existing_file      # modify something
    git commit -a -m 'add new text'       # commit the change
    git revert --no-edit HEAD             # add another commit that undoes change
    git push -f origin branch             # and push
    

    then the update will remove three commits and add two more. The tree you would get if you checked out the new SHA-1 (again, using the old, new, ref triple notation) would look exactly like the version I have asked to push. If there is some test that trees must pass, presumably the version that was HEAD~3 did in fact pass those tests, so this version would too. However, the thing I committed that added one line to existing_file might not pass the tests, and you might not like the fact that I removed three commits.

    So, again, it's up to you to decide what you want to check, and write code to achieve that. Check whether a force-push is removing commits; allow or forbid this. Check whether a new branch name is being created; allow or forbid. Check whether a branch name is being deleted; allow or forbid. If commits are being added, check every intermediate commit's tree, or check only the final tree; allow or forbid. Do commits being added involve merges? Are tags being added, removed, or changed? And so on.

    Just for fun, a while ago I wrote a pre-receive shell script (in POSIX-style shell) that does many of these (it does not check the contents of any commit). I did some very light testing and it seems to work. It could be used as a starting-point for more thorough checking.

    If you're doing serious checking, though, you might want to look into using gitolite.

    这篇关于Git预接收钩子来检查配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆