【问题标题】:Need to validate local and remote branch before push推送前需要验证本地和远程分支
【发布时间】:2017-10-26 11:49:36
【问题描述】:

我正在尝试使用 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

【问题讨论】:

  • 删除else exit 0。确保钩子的名称恰好是 pre-push 并且它是可执行的。
  • 嗨,当我的分支名称相同时,这也给了我错误,因为我正在将我的更改推送到 Gerrit/review 分支因此我的 Local = Mybranch 和 Remote= refs/for/Mybranch 我如何削减参考/for/ 来自 remote_ref 变量?
  • 推送分支时,local_ref 为 refs/heads/Mybranch,remote_ref 为 refs/for/Mybranch。
  • 是的,但我只想将 Mybranch 和 Mybranch 分别作为本地和远程进行比较,所以我正在尝试:同时读取 local_ref local_sha remote_ref remote_sha do remote_ref >> remote.txt remote_ref1 = cat remote.txt | cut -d'/' -f3 rm remote.txt if [ "$local_ref" != "$remote_ref1" ] then echo " Please check Remote and local branch names"\n exit 1 else exit 0 fi done'

标签: git githooks


【解决方案1】:

一般来说,你不应该假设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 来请求同时推送三件事,这就是为什么您必须在 pre-push 挂钩中循环读取所有请求的原因。


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

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 ... 循环。如果您完成了循环,所有您推送的引用都已经过验证(因为没有一个被 echo-and-exit 代码拒绝)。

【讨论】:

  • 接受的答案。感谢您对此的帮助,它对我有用。只有一个帮助,如果您能解释以下提取的工作原理:remote_short=${remote_ref#refs/heads/}
  • shell 有一个精心定义的“变量替换”或“参数扩展”语法(不同的文档对此使用不同的术语)。 $var 是最明显的,但如果你想扩展 $x 后跟字母 y 怎么办?所以他们有${x}y 来做这件事。在大括号内,它们允许进一步修改。细节从一个 shell (bash) 到另一个 shell (sh、dash、ksh 等) 不同,但都支持${var#word},这意味着“删除前导前缀模式”。还有更多:对于 bash,请参阅 wiki.bash-hackers.org/syntax/pe
  • 非常感谢您的帮助!:)
猜你喜欢
  • 1970-01-01
  • 2020-09-05
  • 2021-09-13
  • 2016-10-25
  • 2015-04-02
  • 2013-08-31
  • 2013-09-07
  • 2013-06-10
  • 2011-03-13
相关资源
最近更新 更多