【问题标题】:How to handle new branch in `pre-receive` git script?如何处理`pre-receive` git 脚本中的新分支?
【发布时间】:2018-11-06 23:50:28
【问题描述】:

我有脚本来阻止未解决的合并冲突被推送:

#!/bin/bash

echo "pre-receive HOOK: $old_sha $new_sha"

while read old_sha new_sha refname
do

if git diff "$old_sha" "$new_sha" | grep -qE '^\+(<<<<<<<|>>>>>>>)'; then
    echo "Saw a conflict marker in $(basename "$refname")."
    git diff "$old_sha" "$new_sha" | grep -nE '^\+(<<<<<<<|>>>>>>>)'
    exit 1
fi

done

exit 0

但是当新分支被推送时,我收到下一条错误消息:

致命:坏对象 0000000000000000000000000000000000000000

完整输出:

Counting objects: 77, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (58/58), done.
Writing objects: 100% (77/77), 11.27 KiB | 5.63 MiB/s, done.
Total 77 (delta 52), reused 14 (delta 6)
remote: pre-receive HOOK
remote: fatal: bad object 0000000000000000000000000000000000000000
To https://tracker.feel-safe.net/gitdev/main.git
 * [new branch]        296-ToS-component -> xxx

而且,如您所见,已提交损坏的更改。

如何处理pre-receive钩子中的新分支?

我应该创建update 挂钩吗?

【问题讨论】:

    标签: git githooks


    【解决方案1】:

    这是我所做的:

    我假设每当我们在新分支上提交时,old_sha 的哈希值将是 0000000000000000000000000000000000000000。如果是这种情况,那么我会从 new_sha 向上遍历,直到我得到一个父级,它的 refname(分支名称)与钩子中收到的不同,然后我将那个父级设为我的 old_sha 并照常继续。

            # Check if old_sha is 0000..., if so then a new branch happened, so we need to point old_sha to revision on the parent branch
            if [[ "$old_sha" == "0000000000000000000000000000000000000000" ]]; then
                # point old_sha to the parent revision (commit)
                old_sha="$(git rev-parse $new_sha^)"
                # get the branch name (refname) of the parent
                parent_refname="$(git name-rev $old_sha --name-only)"
                # Travers up until old_sha is the commit (revision) on the parent branch
                while [ "$parent_refname" == "$refname" ]
                do
                    old_sha="$(git rev-parse $old_sha^)"
                    parent_refname="$(git name-rev $old_sha --name-only)"
                done
            fi
    

    所以我会把这段代码放在你的if 语句的正上方。

    我刚刚测试过一次,我不是 git 或 bash 方面的专家,所以请随时指出这会导致问题的任何情况。

    【讨论】:

      【解决方案2】:

      当一个新的 ref 被创建时,old_sha 等于 0000000000000000000000000000000000000000。此哈希没有真实对象,因此 git diff 无法正常工作。如果您需要差异,请改用git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 $new_sha4b825dc642cb6eb9a060e54bf8d69288fbee4904 是空树的哈希值,它可以在没有真实对象的情况下工作。

      你需要处理另一个类似的情况,其中一个 ref 被删除并且new_sha0000000000000000000000000000000000000000。同样,使用git diff $old_sha 4b825dc642cb6eb9a060e54bf8d69288fbee4904 获取差异。

      您可以在.git/hooks 下看到pre-push.sample 以供参考。这是一个很好的示例,它展示了如何处理创建、删除和更新 ref,除了 pre-receive 不带参数而 pre-push 带两个参数。但两者都可以从标准输入中读取内容。

      【讨论】:

      • 虽然这可行,但git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 $new_sha 将输出$new_sha 和空树之间的全部差异,如果您的存储库非常大/旧,这可能会很多。更好的解决方案是区分分支起源的提交。
      猜你喜欢
      • 1970-01-01
      • 2012-08-16
      • 2018-04-28
      • 1970-01-01
      • 2012-09-01
      • 2021-09-30
      • 2013-10-17
      • 1970-01-01
      相关资源
      最近更新 更多