【问题标题】:Can pre-receive hook edit commits?可以预先接收钩子编辑提交吗?
【发布时间】:2026-02-06 13:45:01
【问题描述】:

我正在构建一个预接收挂钩来检查作者的姓名和电子邮件地址。

我可以轻松检查提交的名称/电子邮件地址是否使用,

while read oldsha newsha refname; do
        authorEmail=$(git log -1 --pretty=format:%ae $newsha)
        if [[ $(grep -w $authorEmail ~/.ssh/authorized_keys | wc -w) -gt 1 ]]; then
                        echo "Author Email: $authorEmail"
                        exit 0
                else
                        echo "Unauthorized Email"
                        exit 1
                fi
done

但不是简单地拒绝它,我想用正确的电子邮件替换它。 我已经这样设置了authorized_keys,

environment="UserEmail=user@hostA" ssh-rsa AAAAAA... user@hostA

所以我想做一些类似的事情

if [[ ... ]]; 
    then
        echo "Author Email: $authorEmail"
        exit 0
    else
        echo "Unauthorized Email detected"
        echo "Replacing email with: $UserEmail"
        git commit --amend --author "something <$UserEmail>"
        exit 0
    fi

但正如预期的那样, git commit --amend .. 会抛出一个错误,这应该在工作树中使用。 有什么方法可以在预接收或更新挂钩中完成此操作?

【问题讨论】:

    标签: git bash githooks git-bash


    【解决方案1】:

    Ankit,

    我了解您想要编辑提交以纠正看似“可恢复”的错误的动机。修改提交authorsip 不是解决方法。由于更改提交作者会更改提交的 SHA-1,因此一旦推送提交,本地分支和远程之间的提交历史记录就会不同。这绝对不是你想要的。

    更好的解决方案(当然,如果在您的情况下可行)是向开发人员 git 存储库添加本地 prepare-commit-msg 和/或 commit-msg 挂钩。然后,您可以在处理提交之前更改提交消息。这将解决历史重写问题。不幸的是,您不能强制远程开发人员使用挂钩(git commit --no-verify 将绕过提交检查)。

    因此,我会推荐一种组合方法。通过在提交提交之前提供本地挂钩来检查和纠正作者问题,可以轻松获取正确的电子邮件地址。然后,添加服务器挂钩以防止推送无效或未经授权的作者的提交。遵循您的 repo 规则的开发人员不会受到不便(除了添加钩子),并且您的远程 repo 不会被未经授权的提交作者填充。

    在相关说明中,如果您要做的只是将作者更新为某个默认的“有效”作者,为什么还要麻烦检查未经授权的作者?

    【讨论】:

    • 这与重写提交消息无关。这是关于重写提交作者元数据。
    • 无论您更改提交消息还是提交元数据,原始问题仍然存在。您最终会得到一个新的 SHA-1 用于提交。我修改了答案以反映作者更改而不是提交消息更改。
    • @MichaelMilom 如果我错了,请纠正我,如果我更改提交作者,它会导致不同的 SHA-1,因此与本地相比会有不同的历史记录。这意味着什么?开发人员每次都必须再次从远程拉取同步吗?
    • 我考虑过使用组合,可能与 pre-commit 或 prepare-commit 一起使用,但就像你说的那样,它在本地并且可以使用 no-verify 轻松跳过。这就是为什么我尽可能在服务器端完成此操作。
    • 在服务器停止提交背后的想法是,如果他们选择忽略本地挂钩,则强制开发人员修复问题。除此之外,我知道没有办法完成你想要完成的事情。如果这令人满意,请接受答案(如果您不介意)。谢谢!
    最近更新 更多