代码之家  ›  专栏  ›  技术社区  ›  Heetola

Git预推以防止合并

  •  0
  • Heetola  · 技术社区  · 6 年前

    我为我的Git钩子制作了这个bash脚本,以避免错误地合并。

    在工作中,我们使用git扩展,它会预先填充分支名称,如果您忘记将分支名称前缀设置为refs/for或refs/drafts,那么您的提交将在远程repo上合并,而不进行代码审查。

    这只能发生在拥有合并权的人身上。但有时候有合并权的人会犯这个错误。

    #!/bin/sh
    
    if [[ `grep 'refs/for'` ]]; then 
      echo "push to refs/for/ authorized"
    elif [[ `grep 'refs/drafts/'` ]]; then
      echo "push to refs/drafts/ authorized"
    else
      echo "PUSH DENIED, MERGE DETECTED, please merge using gerrit 'submit' button only"
      exit 1
    fi
    

    如果我推到 refs/for/v1.1.x 它得到 push to refs/for/ authorized

    但是如果我想 refs/drafts/v1.1.x 我得到 PUSH DENIED, MERGE DETECTED, please merge using gerrit 'submit' button only

    怎么可能,条件语法完全相同。

    谢谢。

    1 回复  |  直到 6 年前
        1
  •  1
  •   torek    6 年前

    AS Anthony Sottile commented ,第一个grep命令读取所有输入,检查 refs/for . 你秒 grep 读取剩余的输入;从第一个输入开始读取 全部的 输入的内容中,没有剩余内容。因此第二个永远找不到任何东西。

    你可以用很多不同的方法来处理这个问题。一种方法是将stdin复制到一个临时文件中,您可以反复读取该文件。另一种方法是构造钩子,使您只读取一次输入,检查每行的每个条件。第二种方法显然更有效,尽管这种“明显性”有点虚幻,这取决于我在这里不想讨论的细节。

    不管怎样,我写这个的方式是:

    #! /bin/sh
    
    summary_status=0     # assume all OK initially
    while read lref lhash rref rhash; do
        case $rref in
        refs/for/*|refs/draft/*) echo "push to $rref ok";;
        *) echo "push to $rref not ok"; summary_status=1;;
        esac
    done
    exit $summary_status
    

    这种变体不需要bash特性(因此 /bin/sh 而不是 /bin/bash #! 行);如果您将其更改为可以更改的,请确保更改 哎呀! 线。它只读取输入一次。它还验证您没有运行,例如:

    git push remote master:refs/for/master develop
    

    您的现有脚本将允许(因为一个正常,另一个不正常)。