Git hook prepare-commit-msg 以防止合并禁止的分支 - 将 Ruby 转换为 Bash

Posted

技术标签:

【中文标题】Git hook prepare-commit-msg 以防止合并禁止的分支 - 将 Ruby 转换为 Bash【英文标题】:Git hook prepare-commit-msg to prevent merging forbidden branches - translate Ruby to Bash 【发布时间】:2022-01-23 02:15:49 【问题描述】:

我正在尝试实现一个 git 挂钩,以防止用户将我们的环境分支(除 main 之外)合并到票证分支中。 This hook 正是我所需要的,除了它是用 Ruby 编写的。我需要将我的钩子放在 bash 或 shell 中,这样我们所有的开发人员都可以轻松采用,而无需修改他们的机器。问题是我正在努力弄清楚如何翻译它,因为我没有为 git 编写 bash 脚本的经验。

这是 Ruby 中的脚本:

#!/usr/bin/env ruby
FORBIDDEN_BRANCHES = ["uat", "support"]

def merge?
  ARGV[1] == "merge"
end

def merge_msg
  @msg ||= `cat .git/MERGE_MSG`
end

def from_branch
  @from_branch = merge_msg.match(/Merge branch '(.*?)'/)[1]
end

def from_forbidden_branch?
  FORBIDDEN_BRANCHES.include?(from_branch)
end

if merge? && from_forbidden_branch?
  out = `git reset --merge`
  puts
  puts " STOP THE PRESSES!"
  puts " You are trying to merge #from_branch into your branch."
  puts " Surely you don't mean that?"
  puts
  puts " run the following command now to discard your working tree changes:"
  puts
  puts " git reset --merge"
  puts
  exit 1
end

这就是我到目前为止所得到的......我已经弄清楚了如何设置 FORBIDDEN_BRANCHES 数组,并检查当前正在执行的操作是否是合并。我缺少的是如何获得实际的 FROM_BRANCH (它目前被硬编码为“支持”)

#!/bin/bash
FORBIDDEN_BRANCHES=("uat" "support" "develop")
FROM_BRANCH="support"
FROM_FORBIDDEN=0

for i in $!FORBIDDEN_BRANCHES[@]; do
  if test $FORBIDDEN_BRANCHES[$i] = $FROM_BRANCH
  then
    echo "Merging from $FROM_BRANCH is forbidden"
    FROM_FORBIDDEN=1
  fi
done

echo $FROM_FORBIDDEN

if test "$2" = "merge"
then
    if test $FROM_FORBIDDEN = 1
    then
        echo "STOP!"
        exit 1
    else
        echo "FROM_FORBIDDEN != 1, continuing"
    fi
else
    echo "Not merging"
fi

echo "Got to the end without errors..."

【问题讨论】:

【参考方案1】:

我没有得到答案,但如果其他人需要这个钩子,我确实想出了自己的解决方案。它肯定会更好,因为我在 bash 脚本方面没有经验,但它实现了防止从禁止分支合并到任何其他分支的目标

#!/bin/bash
FORBIDDEN_BRANCHES=("uat" "support" "develop" "origin/uat" "origin/support" "origin/develop")
FROM_BRANCH="null"

MSG=`cat .git/MERGE_MSG`

[[ $MSG =~ ^'Merge branch '(.*) ]] && FROM_BRANCH=$BASH_REMATCH[1]

if test $FROM_BRANCH != "null"
then
    FROM_BRANCH=$(echo $FROM_BRANCH | cut -f 1 -d " ")
    eval BRANCH=$FROM_BRANCH
else
    [[ $MSG =~ ^'Merge remote-tracking branch '(.*) ]] && FROM_BRANCH=$BASH_REMATCH[1]
    FROM_BRANCH=$(echo $FROM_BRANCH | cut -f 1 -d " ")
    eval BRANCH=$FROM_BRANCH
fi

if test $FROM_BRANCH != "null"
then
    for i in $!FORBIDDEN_BRANCHES[@]; do
      if test $FORBIDDEN_BRANCHES[$i] = $BRANCH
      then
        echo "Merging from $BRANCH is forbidden"
        echo "Reset your branch using \"git reset --merge\""
        exit 1
      fi
    done
else
    "NOT COMITTING: FROM_BRANCH = $FROM_BRANCH"
fi

【讨论】:

以上是关于Git hook prepare-commit-msg 以防止合并禁止的分支 - 将 Ruby 转换为 Bash的主要内容,如果未能解决你的问题,请参考以下文章

git hooks 简介与使用

这个git的hook文件具体啥意思,为啥hexo deploy后有这种效果?

Git钩子:'.git/hooks/pre-commit':不允许操作

git hook裸仓库自动部署

Git Hook开发实践总结

Git服务器,仓库的hook监控