推送前需要验证本地和远程分支

Need to validate local and remote branch before push

我正在尝试在 GIT 中使用 Pre-push 挂钩创建一个检查点,我正在检查本地分支和远程分支名称是否相同。

并且仅当本地和远程分支相同时才允许推送。我在预推样本挂钩文件中尝试过类似的东西,但它不起作用。请提出建议。

while read local_ref local_sha remote_ref remote_sha
do
if [ "$local_ref" != "$remote_ref" ]
then
        echo " Please check Remote and local branch names";
        exit 1

else
        exit 0
fi
done

更新:我的本地分支是"git push command"中的Mybranch,远程分支是refs/for/Mybranch

所以即使我的分支名称相同也会给我错误,我怎样才能从远程提取分支名称而不包括 /refs/for?

Git推送命令:

git push origin Mybranch:refs/for/Mybranch

一般来说,您不应该假设 refs/heads/refs/for/,因为对于标签推送 (refs/tags/) 和其他推送(例如, refs/notes/,也许 refs/stash,等等)。

请注意,您(或任何人)可以运行,例如,git push there refs/heads/master:refs/for/something refs/tags/v1.2:refs/tags/v1.2 refs/remotes/origin/master:refs/heads/master请求同时推送三件事情,这就是为什么您必须在预推钩.


您在评论中建议您正在使用:

remote_ref >> remote.txt
remote_ref1 = cat remote.txt | cut -d'/' -f3
rm remote.txt

其中有一些语法错误。

检查 前缀是更明智的做法,如果它是您期望和希望处理的,则去掉前缀。不要只提取第三个单词,因为如果您使用名为 feature/tall 的分支,或者正在处理具有前两个组件之外的附加结构的引用(远程跟踪分支以这种方式工作,例如,虽然通常你不会推动它们)。

在sh/bash脚本语言中,您可以这样写,例如:

case $local_ref in
refs/heads/*)
    local_type=branch
    local_short=${local_ref#refs/heads/}
    ;;
*)
    local_type=unknown
    ;;
esac

case $remote_ref in
refs/heads/*)
    remote_type=branch
    remote_short=${remote_ref#refs/heads/}
    ;;
refs/for/*)
    remote_type=gerrit
    remote_short=${remote_ref#refs/for/}
    ;;
*)
    remote_type=unknown
    ;;
esac

现在您已经解码了引用类型并找到了已知案例的简短版本,您可以编写每个案例的逻辑,并在以后适当地扩展它:

case $local_type,$remote_type in
branch,branch|branch,gerrit)
    # push from branch to branch, or from branch to gerrit:
    # require that the shortened names match exactly (for now)
    if [ $local_short != $remote_short ]; then
        echo "push to $remote_type requires paired names" 1>&2
        echo "but you are pushing from $local_short to $remote_short" 1>&2
        exit 1
    fi
    ;;
*)
    # echo "unknown reference type - allowing" 1>&2 # uncomment for debug
    ;;
esac

所有这些都将进入主 while read ... 循环。如果你到达循环的末尾,所有 你推送的引用都已经过验证(因为 none 被 echo-and-exit 代码拒绝)。