推送前需要验证本地和远程分支
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 代码拒绝)。
我正在尝试在 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 代码拒绝)。