不小心将测试分支代码合并到生产分支去了?写个钩子一键检测

说在前面

🎈在我们使用git进行开发的过程中,我们一般会有几种分支:生产分支、测试分支、需求开发分支、bug修复分支等......在多分支开发的过程中,测试分支的代码是不应该直接被合并到生产分支中去的,但总会有人不小心从测试分支拉了新分支出来进行开发,最后在不知情的情况下将测试分支的代码合并到了生产分支中去,那么能不能在commit前就避免这种情况发生呢?

效果展示

Git Flow

Git Flow 是一种针对 Git 版本控制系统的分支管理和工作流模型,由 Vincent Driessen 提出,旨在帮助团队更有效地协作和管理项目。它定义了一系列的分支和它们的使用规则,以支持高效的开发流程和版本发布管理。

以下是 Git Flow 规范的主要组成部分和它们的使用场景:

1. 永久分支 (Permanent Branches)

  • Master Branch:

    • 用于发布到生产环境的代码。
    • 每次提交都有对应的标签 (Tag)。
    • 只接受从其他分支合并过来的代码,不允许直接修改。
  • Develop Branch:

    • 主开发分支,包含所有准备发布到下一个版本的代码。
    • 作为集成分支,所有其他分支的代码最终都合并回此分支。
    • 定期从 Master 分支拉取更新,以保持与生产环境的同步。

2. 临时分支 (Temporary Branches)

  • Feature Branches (feat-):

    • 用于开发新功能。
    • 从 Develop 分支拉取。
    • 完成开发后,合并回 Develop 分支。
    • 合并完成后,通常删除 Feature 分支。
  • Release Branches (release-):

    • 用于准备发布新版本。
    • 从 Develop 分支创建。
    • 可以进行测试、修改 Bug 等。
    • 发布完成后,合并到 Master 和 Develop 分支,并删除 Release 分支。
  • Hotfix Branches (hotfix-):

    • 用于修复生产环境中的紧急 Bug。
    • 从 Master 分支拉取。
    • 修复完成后,合并回 Master 和 Develop 分支。
    • 并在 Master 分支上打上标签。

3. 工作流程

  • 功能开发:

    • 开发人员从 Develop 分支创建 Feature 分支进行功能开发。
    • 功能完成后,通过 Pull Request (PR) 合并回 Develop 分支。
  • 版本发布:

    • 当准备发布新版本时,从 Develop 分支创建 Release 分支。
    • 在 Release 分支上完成最后的测试和 Bug 修复。
    • 确认无误后,合并 Release 分支到 Master 和 Develop 分支,并打上版本标签。
  • 紧急修复:

    • 发现生产环境中的问题时,从 Master 分支创建 Hotfix 分支进行修复。
    • 修复完成后,立即合并回 Master 和 Develop 分支,并打上修复标签。

4. 注意事项

  • 避免使用 git rebase 改变共有分支上的提交历史。
  • 使用 git merge 来合并分支,以保留完整的提交记录。
  • 定期从 Master 分支拉取更新到 Develop 分支,以保持同步。
  • 功能分支和 Release 分支在合并后通常被删除。

Git Flow 规范通过明确的分支策略和合并规则,帮助团队成员理解各自的角色和责任,减少冲突,提高协作效率。它特别适合于需要定期发布新版本的项目,能够确保代码质量和发布流程的稳定性。

钩子编写

1、设置颜色变量

shell 复制代码
color_red="\e[0;31m"
color_blue="\e[34m"
color_reset="\e[00m"

定义了三个颜色变量,用于在终端中以红色、蓝色和默认颜色显示文本。

2、获取当前分支

shell 复制代码
currBranch=$(git symbolic-ref --short HEAD 2>/dev/null)
if [ $? -ne 0 ]; then
    echo -e "${color_red}获取当前分支失败,请确保当前目录在 Git 仓库中${color_reset}"
    exit 0
fi

使用 git symbolic-ref --short HEAD 命令获取当前的 Git 分支名,并将其存储在变量 currBranch 中。如果命令执行失败(即当前目录不在 Git 仓库中),脚本会输出错误信息并退出。

3、获取已合并分支列表

shell 复制代码
mergedList=$(git branch --merged $currBranch)

使用 git branch --merged 命令列出所有已经合并到当前分支的分支。这些分支名被存储在 mergedList 变量中。

4、搜索特定分支

shell 复制代码
IFS=$'\n' read -d '' -ra array <<< "$mergedList"

search="test"
found=false

for item in "${array[@]}"; do
    item_without_spaces=${item//[[:space:]]/}
    if [[ "$item_without_spaces" == "$search" ]]; then
        found=true
        break
    fi
done

脚本设置了一个搜索字符串 search(在这个例子中是 "test"),并初始化一个布尔变量 found 为 false。然后,脚本遍历 mergedList 中的每个分支,去除空格后检查是否与 search 字符串匹配。如果找到匹配的分支,found 被设置为 true 并退出循环。

5、输出结果

shell 复制代码
if $found; then
    echo -e "${color_red}当前分支($currBranch) 包含了 $search 分支合并记录${color_reset}"

如果 found 为 true,表示当前分支包含了 search 字符串指定的分支的合并记录。脚本会输出这一信息,并提示用户确认是否继续提交。用户可以输入 "N" 或 "n" 来取消操作,或者输入 "Y" 或 "y" 来确认提交。

6、用户输入处理

shell 复制代码
read -p "请确定是否提交?(N/Y): " confirm </dev/tty
case "$confirm" in
    n|N):
        echo "已取消"
        exit 1
    ;;
    y|Y):
        # 选择了确认
        exit 0
    ;;
    *)
        echo 2>&1 "已取消"
        exit 2
    ;;
esac

脚本使用 read 命令从终端读取用户输入,并根据输入的内容执行不同的操作:

  • 如果用户输入 "N" 或 "n",则输出 "已取消" 并退出脚本,返回状态码 1。
  • 如果用户输入 "Y" 或 "y",则退出脚本,返回状态码 0,表示确认提交。
  • 如果用户输入其他字符,脚本会输出 "已取消" 并退出脚本,返回状态码 2。

7、退出脚本

根据用户的选择,脚本以不同的状态码退出。状态码 0 通常表示成功或正常退出,而非零状态码表示某种错误或异常情况。

完整代码

javascript 复制代码
#! /bin/sh

color_red="\e[0;31m"
color_blue="\e[34m"
color_reset="\e[00m"

currBranch=$(git symbolic-ref --short HEAD 2>/dev/null)
if [ $? -ne 0 ]; then
    echo -e "${color_red}获取当前分支失败,请确保当前目录在 Git 仓库中${color_reset}"
    exit 0
fi

mergedList=$(git branch --merged $currBranch)

IFS=$'\n' read -d '' -ra array <<< "$mergedList"

search="test"
found=false

for item in "${array[@]}"; do
    item_without_spaces=${item//[[:space:]]/}
    if [[ "$item_without_spaces" == "$search" ]]; then
        found=true
        break
    fi
done

# 输出结果
if $found; then
    echo -e "${color_red}当前分支($currBranch) 包含了 $search 分支合并记录${color_reset}"
    read -p "请确定是否提交?(N/Y): " confirm </dev/tty
    case "$confirm" in
        n|N):
            echo "已取消"
            exit 1
        ;;
        y|Y):
            # 选择了确认
            exit 0
        ;;
        *)
            echo 2>&1 "已取消"
            exit 2
        ;;
    esac
fi

公众号

关注公众号『前端也能这么有趣』,获取更多有趣内容。

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。

相关推荐
昨天;明天。今天。1 小时前
案例-表白墙简单实现
前端·javascript·css
数云界1 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd1 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常1 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer1 小时前
Vite:为什么选 Vite
前端
小御姐@stella1 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing1 小时前
【React】增量传输与渲染
前端·javascript·面试
eHackyd1 小时前
前端知识汇总(持续更新)
前端
Good_Starry4 小时前
Git介绍--github/gitee/gitlab使用
git·gitee·gitlab·github
万叶学编程5 小时前
Day02-JavaScript-Vue
前端·javascript·vue.js