【问题标题】:How to check that git commits contain string pattern in message?如何检查 git 提交是否在消息中包含字符串模式?
【发布时间】:2017-11-30 12:59:29
【问题描述】:

我有一个包含一些项目的 GitLab 存储库。我想检查提交消息是否包含正则表达式字符串模式(例如,'[0-9]{3}'),以供想要推送他对项目的提交的人使用。如果用户的提交消息中没有字符串模式,则为该用户返回消息“您的提交消息不包含必要的字符串模式”。

我知道有 git 钩子,我可以在这里写自己的:/var/opt/gitlab/git-data/repositories/root/awesome.git/custom_hooks/pre-receive 但如何检索用户的提交消息?

【问题讨论】:

    标签: git hook githooks


    【解决方案1】:

    在 pre-receive 或 update 钩子中,您会在标准输入上或作为参数获得一个 引用名称、引用的 旧值,以及引用的新值。更新挂钩获得一个引用,作为参数。您可以根据这三个参数对单个参考更新做出单一决定:允许或阻止它。 pre-receive 钩子在其标准输入上获取所有建议的更新,每行一个,并且您必须在做出一个决定之前阅读所有标准输入:允许将所有建议的更新传递到下一步(包括运行更新挂钩,一次一个名称)或拒绝整个更新。

    在所有情况下,每个参考都使用其完整的拼写格式。请务必使用所有这些,以免您将 tag Xrefs/tags/X 误认为是命名为 branch X 的不同引用 refs/heads/X .同样,不要将分支名称refs/heads/experiment/masterrefs/heads/master 混淆,如果您只是将所有内容从最后一个/ 剥离(即包括),就会发生这种情况。您甚至可能会收到更新既不是分支名称​​也不是标记名称的引用的请求,例如refs/replace/ 命名空间项或refs/notes/commits

    类似地,旧值和新值是两个完整的 Git 哈希 ID,只是其中一个(绝不是两者)可能是特殊的全零“空哈希”。 null 哈希表示引用正在创建(旧值 null,新值非 null)或销毁(旧值非 null,新值 null)。

    查看提交

    如果您希望查看所有传入提交的消息,则必须遍历 $oldhash..$newhash 中的每个提交,除非您必须以不同方式处理“正在创建的引用”或“正在销毁的引用”。当一个引用被创建时,有时不可能知道哪个提交,如果有进来了,因为那个新的引用。例如,考虑一下你的 pre-receive 钩子获取的情况:

    012...789 aaa...aaa refs/heads/br1
    345...eee 321...def refs/heads/br2
    000...000 999...999 refs/tags/v2.1
    

    现在,refs/tags/v2.1 正在创建中(它的旧值是全零)。它的新值是999...,大概是一个带注释的标签对象或一个提交对象。但是如果999... 到达一个提交,其父级是888... 并且 888... 之前不在存储库中?那么新创建的标签可能就是提交888...的来源。另一方面,br1br2 两个分支名称也正在更改。如果其中一个也达到888... 怎么办? (例如,这可能是 aaa... 的祖父母提交。)

    最接近“新引用引入的提交”的方法是使用git rev-list <hash> --not --all 获取可通过哈希 ID 访问的提交列表,这些提交列表尚未从所有现有引用中访问。这会将新提交 888... 视为可从标签访问,即使它也 br1 可访问(当然,前提是您允许更新到 br1)。

    对于您的情况,这可能没问题:如果您因在 br1 上有错误消息而拒绝提交,您也可以因在 v1.2 上有错误消息而拒绝提交,这意味着您拒绝提交两次,但那又怎样?或者它可能很好,在这种情况下,你必须决定你希望如何处理它。请记住,您的选择是在 pre-receive 挂钩中读取 all 更新,并允许它们全部继续或全部拒绝;或在更新挂钩中检查每次更新一个,并允许该更新继续进行,或拒绝它。在 pre-receive 钩子中,由于您拥有所有更新的全局视图,因此您可以编写花哨的逻辑。在更新钩子中,你的视野很窄,你不能编写花哨的逻辑:你必须保持简单。各有优缺点。

    无论如何,一旦你有了更新,你就可以知道哪些提交在更新后可以访问,而哪些提交是不可达的:

    git rev-list $newvalue ^$oldvalue | ...
    

    并且您可以从不再可访问的旧参考值中判断哪些提交是可访问的:

    git rev-list $oldvalue ^$newvalue | ...
    

    (后者是通过强制推送删除的提交)。在代码的... 部分,您可以读取每个提交哈希并对其进行任何您喜欢的操作,例如:

    ... | while read hash; do
        if git log --format=%B $hash | grep "$expr" >/dev/null; then
            # grep found a pattern in the body printed by %B
        else
            # grep did not find the pattern
        fi
    done
    

    【讨论】:

    • 感谢您的详细解释!
    猜你喜欢
    • 1970-01-01
    • 2021-08-04
    • 2017-09-13
    • 1970-01-01
    • 2020-12-04
    • 2022-11-02
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多