如何检查 git 提交是否在消息中包含字符串模式?
How to check that git commits contain string pattern in message?
我有一个包含一些项目的 GitLab 存储库。我想检查提交消息是否包含正则表达式字符串模式(例如,'[0-9]{3}'),以供想要推送他对项目的提交的人使用。如果用户的提交消息中没有字符串模式,则该用户的 return 消息 "Your commit's message doesn't contain necessary string pattern"。
我知道有 git 钩子,我可以在这里编写自己的钩子:/var/opt/gitlab/git-data/repositories/root/awesome.git/custom_hooks/pre-receive
但是我如何检索用户的提交消息?
在 pre-receive 或更新挂钩中,您在标准输入上或作为参数给出了一个 引用名称 , 旧值 和参考的 新值 。更新挂钩获取一个引用作为参数。您可以根据这三个参数对单个引用更新做出单一决定:允许它或阻止它。 pre-receive 挂钩在其标准输入上获取 all 建议的更新,每行一个,您必须阅读标准输入的 all在做出你的一个决定之前:允许所有建议的更新传递到下一步——包括 运行 更新挂钩,一次一个名称——或者拒绝整个更新。
在所有情况下,每个引用都使用其完整的 spelled-out 格式。请务必全部使用,以免将 tag X
、refs/tags/X
误认为是命名 分支X
。同样,不要将分支名称 refs/heads/experiment/master
与 refs/heads/master
混淆,如果您简单地剥离(即包括)最后的 /
中的所有内容,就会发生这种情况。您甚至可能会收到更新既不是分支名称 也不是 标签名称的引用的请求,例如 refs/replace/
name-space 项目,或 refs/notes/commits
.
类似地,旧值和新值是两个完整的 Git 哈希 ID,除了恰好一个——永远不会是两个——可能是特殊的 all-zeros "null hash"。 null 散列表示正在创建引用(旧值 null,新值 non-null)或销毁(旧值 non-null,新值 null)。
查看提交
如果您希望查看所有传入提交的消息,则必须遍历 $oldhash..$newhash
中的每个提交,但您必须以不同方式处理 "reference being created" 或 "reference being destroyed"。创建引用时,有时无法知道如果有任何 由于那个新引用而进入了哪个提交。例如,考虑您的 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
(其旧值为 all-zeros)。它的新值是 999...
,大概是一个带注释的标签 object 或一个提交 object。但是,如果 999...
到达 parent 是 888...
和 888...
之前不在存储库中的提交怎么办?那么新创建的标签可能就是提交的来源888...
。另一方面,两个分支名称 br1
和 br2
也正在更改。如果其中之一也达到 888...
怎么办? (例如,也许那是 aaa...
的盛大 parent 提交。)
最接近 "commits introduced by new reference" 的方法是使用 git rev-list <hash> --not --all
获取哈希 ID 可访问的提交列表,这些提交尚未从所有现有引用中访问。这会将新提交 888...
计为可从标签访问,即使它也 将是 可从 br1
访问(前提是您允许更新到 br1
当然)。
对于你的情况,这可能没问题:如果你拒绝在 br1
上有错误消息的提交,你也可以拒绝在 v1.2
上有错误消息的提交,这意味着你拒绝了两次提交,但那又怎样?或者它可能 not 没问题,在这种情况下,您必须决定您希望如何处理它。请记住,您的选择是在 pre-receive 挂钩中读取 所有 更新,并允许它们全部继续或全部拒绝;或在更新挂钩中检查每个更新一次,并允许该更新继续,或拒绝它。在 pre-receive 挂钩中,由于您拥有所有更新的全局视图,因此您可以编写花哨的逻辑。在更新挂钩中,您的视野狭窄,您不能编写花哨的逻辑:您必须保持简单。各有优缺点。
无论如何,一旦有了更新,您就可以判断哪些提交在更新后可以访问,哪些还无法访问:
git rev-list $newvalue ^$oldvalue | ...
并且您可以根据不再可访问的旧参考值判断哪些提交是可访问的:
git rev-list $oldvalue ^$newvalue | ...
(后者是通过 force-push 删除 的提交)。在代码的 ...
部分,您可以读取每个提交哈希并对其进行任何您喜欢的操作,例如:
... | 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
我有一个包含一些项目的 GitLab 存储库。我想检查提交消息是否包含正则表达式字符串模式(例如,'[0-9]{3}'),以供想要推送他对项目的提交的人使用。如果用户的提交消息中没有字符串模式,则该用户的 return 消息 "Your commit's message doesn't contain necessary string pattern"。
我知道有 git 钩子,我可以在这里编写自己的钩子:/var/opt/gitlab/git-data/repositories/root/awesome.git/custom_hooks/pre-receive
但是我如何检索用户的提交消息?
在 pre-receive 或更新挂钩中,您在标准输入上或作为参数给出了一个 引用名称 , 旧值 和参考的 新值 。更新挂钩获取一个引用作为参数。您可以根据这三个参数对单个引用更新做出单一决定:允许它或阻止它。 pre-receive 挂钩在其标准输入上获取 all 建议的更新,每行一个,您必须阅读标准输入的 all在做出你的一个决定之前:允许所有建议的更新传递到下一步——包括 运行 更新挂钩,一次一个名称——或者拒绝整个更新。
在所有情况下,每个引用都使用其完整的 spelled-out 格式。请务必全部使用,以免将 tag X
、refs/tags/X
误认为是命名 分支X
。同样,不要将分支名称 refs/heads/experiment/master
与 refs/heads/master
混淆,如果您简单地剥离(即包括)最后的 /
中的所有内容,就会发生这种情况。您甚至可能会收到更新既不是分支名称 也不是 标签名称的引用的请求,例如 refs/replace/
name-space 项目,或 refs/notes/commits
.
类似地,旧值和新值是两个完整的 Git 哈希 ID,除了恰好一个——永远不会是两个——可能是特殊的 all-zeros "null hash"。 null 散列表示正在创建引用(旧值 null,新值 non-null)或销毁(旧值 non-null,新值 null)。
查看提交
如果您希望查看所有传入提交的消息,则必须遍历 $oldhash..$newhash
中的每个提交,但您必须以不同方式处理 "reference being created" 或 "reference being destroyed"。创建引用时,有时无法知道如果有任何 由于那个新引用而进入了哪个提交。例如,考虑您的 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
(其旧值为 all-zeros)。它的新值是 999...
,大概是一个带注释的标签 object 或一个提交 object。但是,如果 999...
到达 parent 是 888...
和 888...
之前不在存储库中的提交怎么办?那么新创建的标签可能就是提交的来源888...
。另一方面,两个分支名称 br1
和 br2
也正在更改。如果其中之一也达到 888...
怎么办? (例如,也许那是 aaa...
的盛大 parent 提交。)
最接近 "commits introduced by new reference" 的方法是使用 git rev-list <hash> --not --all
获取哈希 ID 可访问的提交列表,这些提交尚未从所有现有引用中访问。这会将新提交 888...
计为可从标签访问,即使它也 将是 可从 br1
访问(前提是您允许更新到 br1
当然)。
对于你的情况,这可能没问题:如果你拒绝在 br1
上有错误消息的提交,你也可以拒绝在 v1.2
上有错误消息的提交,这意味着你拒绝了两次提交,但那又怎样?或者它可能 not 没问题,在这种情况下,您必须决定您希望如何处理它。请记住,您的选择是在 pre-receive 挂钩中读取 所有 更新,并允许它们全部继续或全部拒绝;或在更新挂钩中检查每个更新一次,并允许该更新继续,或拒绝它。在 pre-receive 挂钩中,由于您拥有所有更新的全局视图,因此您可以编写花哨的逻辑。在更新挂钩中,您的视野狭窄,您不能编写花哨的逻辑:您必须保持简单。各有优缺点。
无论如何,一旦有了更新,您就可以判断哪些提交在更新后可以访问,哪些还无法访问:
git rev-list $newvalue ^$oldvalue | ...
并且您可以根据不再可访问的旧参考值判断哪些提交是可访问的:
git rev-list $oldvalue ^$newvalue | ...
(后者是通过 force-push 删除 的提交)。在代码的 ...
部分,您可以读取每个提交哈希并对其进行任何您喜欢的操作,例如:
... | 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