githooks之防止分支误合并

在多人协作时,我们会把各自的分支开发的功能合并入test分支。有的分支可能有当前版本不能上的代码。这时如果有人将test分支合到自己当前需要发的分支中,会将自己分支给污染,一不注意就会影响整个系统当前版本上线;我们一般会约定test分支只可合入代码,而不能将其合入其它分支。约定的有时一不注意就会出错,因此这里我们将通过自动化检测防止分支误合并,通过硬性机制控制

基本原理

  • githooksprepare-commit-msgpost-commitpost-merge 钩子
  • child_process node子进程执行shell
  • git tag标记合并前代码便于回退
  • git reset --hard回退代码
  • git symbolic-ref --short -q HEAD 获取当前分支名
  • git log --grep= 过滤commit提交记录

基本流程

在这里插入图片描述

  • 合并前触发prepare-commit-msg 钩子 判断是否为测试分支(不可合并入其它分支),不是开发分支则打标签
  • 合并后触发post-merge钩子 非不可合并分支时查询提交记录里是否有不可合并分支名称记录,命中则根据标签还原
  • 只是commit提交后,为防止推送是和远程tag冲突 需触发post-commit删除tag

源码(基于node)

  • 工具库
const childprocess = require('child_process');

// 检查提交记录是否包含name
function checkMerge(name){
  return new Promise(function (resolve,reject){
    childprocess.exec(`git log --grep="Merge branch '${name}'"`,(err,stdout,stderr)=>{
      if (err !== null) {
        return reject(err)
      }
      return resolve(!!stdout)
    })
  })
}
// 检查当前分支是否为name
function checkBranch(name){
  return new Promise(function(resolve,reject){
    childprocess.exec(`git symbolic-ref --short -q HEAD`,(err,stdout,stderr)=>{
      if (err !== null) {
        return reject(err)
      }
      return resolve(stdout.search(name)===0)
    })
  })
}
module.exports={checkMerge,checkBranch}
  • prepare-commit-msg执行脚本
const  {checkBranch} =require('./mergelint.util.js')
async function main(){
  // 检查是否为测试分支或者开发分支
  const res = await checkBranch(/operate_test|operate_dev/)
  // 不为开发分支
  if(!res){
    // 打标签
    const childprocess = require('child_process');
    childprocess.exec(`git tag -d m0.1.0`,function(){
    childprocess.exec(`git tag -a m0.1.0 -m "合并分支暂存"`,function (error, stdout, stderr) {
              if (error !== null) {
                console.log('exec error: ' + error);
              }
              console.log('打标签成功')
    });
  })
  }
}
main()
  • post-merge执行脚本
const  {checkBranch,checkMerge} =require('./mergelint.util.js')
async function main(){
  const res = await checkBranch(/operate_test|operate_dev/)
  if(res){
  	childprocess.exec(`git tag -d m0.1.0`,function(){})
    return true
  }
  // 检查是否含测试分支
  const resM = await checkMerge('operate_test')
  const resM2 = await checkMerge('operate_dev')
  // 为开发分支
  if(resM||resM2){
    // 还原
    const childprocess = require('child_process');
    childprocess.exec(`git reset --hard m0.1.0`,function (error, stdout, stderr) {
              if (error !== null) {
                console.log('当前分支被污染,请手动处理!')
                return
              }
              console.log('请不要合并test和dev分支到当前分支!')
              childprocess.exec(`git tag -d m0.1.0`,function(){})
    });
  }else{
    childprocess.exec(`git tag -d m0.1.0`,function(){})
  }
}
main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值