赞
踩
每月迭代结束,都不会主动去删除自己创建的分支,而仓库分支几年都没有清理,导致branchs差不多2k条。
一、用脚本实现批量删除,无需手动执行git命令批量操作
二、支持筛选条件,如:已合并的分支、最后一次commit在三个月前、包含release字符的分支
- #!/bin/bash
-
- repository_name="$1"
- echo "您即将删除【"$repository_name"】下的分支,请先找其他人备份好,以免误删!!!!";
- echo " "
-
- # 过滤条件,将无需删除的分支加入到这个数组中
- excluded_branches=("master" "develop")
-
- # 指定要过滤的分支名称中需包含的字符(为空则不进行该过滤)
- excluded_filter="release/1."
-
- # 指定要删除的分支名称中需包含的字符(为空则不进行该过滤)
- # include_filter=""
-
- # 获取当前系统时间的秒数
- current_time=$(date +%s)
-
- # 计算三个月前的时间戳
- three_months_ago=$((current_time - 3600 * 24 * 90))
-
- # 计算两个月前的时间戳
- two_months_ago=$((current_time - 3600 * 24 * 60))
-
- # 计算一个月前的时间戳
- one_months_ago=$((current_time - 3600 * 24 * 30))
-
-
- # 获取所有已合并的远程分支,并进行循环处理
- for branch in `git branch -r --merged origin/master | grep -v HEAD`; do
- # 提取分支名称
- # simple_name=$(echo "$branch" | grep '/' | cut -d'/' -f 2);
-
- simple_name=$(echo "$branch" | sed 's#.*origin/##')
-
- # 排除不需要删除的分支
- excluded_flag="0";
- for excluded_branch in "${excluded_branches[@]}"; do
- if [[ "$simple_name" == "$excluded_branch" ]]; then
- excluded_flag="1";
- break
- fi
- done
-
- # 判断是否满足删除条件
- if [[ $excluded_flag == "0" ]]; then
- if [[ -n $excluded_filter ]]; then
- if [[ "$simple_name" == *"$excluded_filter"* ]]; then
- continue
- fi
- fi
-
- # if [[ -n $include_filter ]]; then
- # if [[ "$simple_name" != *"$include_filter"* ]]; then
- # continue
- # fi
- # fi
-
- # 获取分支最后提交时间
- branch_timestamp=$(git show --format="%at" "$branch" | head -n1)
-
- # 根据实际需要选择 三个月前 $three_months_ago 两个月$two_months_ago 一个月前$one_months_ago 当前$current_time
- if [[ $branch_timestamp -lt $three_months_ago ]]; then
- echo "正在删除分支: $simple_name"
-
- # 删除本地分支
- # git branch -d "$simple_name"
-
- # 删除远程分支
- git push origin --delete "$simple_name"
-
- echo "分支 $simple_name 删除完成"
- echo ""
- fi
- fi
- done
- echo "清除结束"

原因:删除分支过后,会出现本地与远端不一致的情况,导致去删除不存在的分支(通过pull无法解决)
解决方法:增加更新远端与本地引用命令
增加更新远端与本地引用命令
- #!/bin/bash
-
- repository_name="$1"
- echo "您即将删除【"$repository_name"】下的分支,请先找其他人备份好,以免误删!!!!";
- echo " "
-
- # 过滤条件,将无需删除的分支加入到这个数组中
- excluded_branches=("master" "develop")
-
- # 指定要过滤的分支名称中需包含的字符(为空则不进行该过滤)
- excluded_filter="release/1."
-
- # 指定要删除的分支名称中需包含的字符(为空则不进行该过滤)
- include_filter=""
-
- # 获取当前系统时间的秒数
- current_time=$(date +%s)
-
- # 计算三个月前的时间戳
- three_months_ago=$((current_time - 3600 * 24 * 90))
-
- # 计算两个月前的时间戳
- two_months_ago=$((current_time - 3600 * 24 * 60))
-
- # 计算一个月前的时间戳
- one_months_ago=$((current_time - 3600 * 24 * 30))
-
- echo "更新本地与远端的分支引用"
-
- # 先更新分支引用,确保git branch -r拉取的分支信息,与远端仓库一致(有删除过分支会出现不一致的情况,导致不必要的遍历)
- git remote update origin --prune
-
- echo "更新完毕,开始批量删除目标分支"
-
- # 获取所有已合并的远程分支,并进行循环处理
- # for branch in `git branch -r --merged origin/master | grep -v HEAD`; do
-
- # 获取所有的远程分支,并进行循环处理
- for branch in `git branch -r | grep -v HEAD`; do
- # 提取分支名称
- # simple_name=$(echo "$branch" | grep '/' | cut -d'/' -f 2);
-
- simple_name=$(echo "$branch" | sed 's#.*origin/##')
-
- # 排除不需要删除的分支
- excluded_flag="0";
- for excluded_branch in "${excluded_branches[@]}"; do
- if [[ "$simple_name" == "$excluded_branch" ]]; then
- excluded_flag="1";
- break
- fi
- done
-
- # 判断是否满足删除条件
- if [[ $excluded_flag == "0" ]]; then
- if [[ -n $excluded_filter ]]; then
- if [[ "$simple_name" == *"$excluded_filter"* ]]; then
- continue
- fi
- fi
-
- if [[ -n $include_filter ]]; then
- if [[ "$simple_name" != *"$include_filter"* ]]; then
- continue
- fi
- fi
-
- # 获取分支最后提交时间
- branch_timestamp=$(git show --format="%at" "$branch" | head -n1)
-
- # 根据实际需要选择 三个月前 $three_months_ago 两个月$two_months_ago 一个月前$one_months_ago 当前$current_time
- if [[ $branch_timestamp -lt $three_months_ago ]]; then
- echo "正在删除分支: $simple_name"
-
- # 删除本地分支
- # git branch -d "$simple_name"
-
- # 删除远程分支
- git push origin --delete "$simple_name"
-
- echo "分支 $simple_name 删除完成"
- echo ""
- fi
- fi
- done
- echo "清除结束"

加上询问交互
inquirer中文文档|inquirer js中文教程|解析 | npm中文文档
用""包裹参数,不能只用空格分隔
nodejs 如何执行 shell 命令,并把结果实时回显输出?
Child process | Node.js v21.1.0 Documentation
解决方案:
用spawn替换exec
问题:这种写法会导致打印输出所有分支到控制台
解决:
- const inquirer = require('inquirer');
- const { spawn } = require('child_process');
-
-
- const format = {
- three_months_ago: '90天前',
- two_months_ago: '60天前',
- one_months_ago: '30天前',
- current_time: '当前',
- branch_all: '所有分支',
- branch_merged: '已合并',
- branch_no_merged: '未合并',
- }
- const label = {
- name: '当前项目是:',
- excluded_filter: '指定要过滤的分支名称中需包含的字符:',
- include_filter: '指定要删除的分支名称中需包含的字符:',
- date_range: '过滤日期范围:',
- branch_rule: '获取远程分支范围:',
- }
-
- const question = [{
- type: 'input',
- message: '当前项目是:',
- name: 'name',
- default: 'ircloud-ydp-web'
- },
- {
- type: 'input',
- message: '指定要过滤的分支名称中需包含的字符(为空则不进行该过滤):',
- name: 'excluded_filter',
- default: 'release/1.'
- },
- {
- type: 'input',
- message: '指定要删除的分支名称中需包含的字符(为空则不进行该过滤):',
- name: 'include_filter',
- default: ''
- },
- {
- type: 'list',
- message: '过滤日期范围:',
- name: 'date_range',
- choices: ['three_months_ago', 'two_months_ago', 'one_months_ago', 'current_time'],
- default: 'three_months_ago',
- },
- {
- type: 'list',
- message: '获取远程分支范围(全部、已合并、未合并):',
- name: 'branch_rule',
- choices: ['branch_all', 'branch_merged', 'branch_no_merged'],
- default: 'branch_all',
- }]
-
-
- let answer = {}
-
- function getParams () {
- return inquirer.prompt(question).then(res => {
- console.log(res)
- answer = {...res}
- })
- }
-
- function confirmAgain () {
- const str = Object.keys(answer).reduce((prev, curr) => {
- if(['date_range', 'branch_rule'].includes(curr)) {
- prev += `${label[curr]} ${format[answer[curr]]}; `;
- }else{
- prev += `${label[curr]} ${answer[curr]}; `;
- }
- return prev;
- }, '')
- return inquirer.prompt([{
- type: 'list',
- message: `${str},确定吗?`,
- name: 'answer',
- choices: ['yes', 'no'],
- default: 'yes'
- }]).then(res => {
- if (res.answer === 'yes') {
- // let params = Object.values(res).reduce((prev, curr) => {
- // prev += `"${curr}" `;
- // return prev
- // }, '')
- // console.log(`bash scripts/delBranch.sh ${params}`);
- // exec(`bash scripts/delBranch.sh ${params}`,(error, stdout, stderr) => {
- // console.log(stdout);
- // console.log(stderr);
- // if (error !== null) {
- // console.log(`exec error: ${error}`);
- // }
- // })
- console.log('参数获取完毕,开始执行删除脚本');
- let paramsArr = Object.values(answer);
- const childProcess = spawn('sh', [`scripts/delBranch.sh`, ...paramsArr]);
- childProcess.stdout.on('data', (data) => {
- console.log(`脚本执行输出:${data}`);
- });
- childProcess.stderr.on('data', (data) => {
- console.error(`脚本错误信息:${data}`)
- })
- } else {
- console.log('终止执行');
- }
- })
- }
-
-
- async function main() {
- await getParams();
- await confirmAgain();
- }
-
- main();

- #!/bin/bash
-
- repository_name="$1"
- echo "您即将删除【"$repository_name"】下的分支,请先找其他人备份好,以免误删!!!!";
- echo " "
-
- # 过滤条件,将无需删除的分支加入到这个数组中
- excluded_branches=("master" "develop")
-
- # 指定要过滤的分支名称中需包含的字符(为空则不进行该过滤)
- # excluded_filter="release/1."
- excluded_filter=$(echo ${2})
-
- # 指定要删除的分支名称中需包含的字符(为空则不进行该过滤)
- include_filter=$(echo ${3})
-
- # 获取当前系统时间的秒数
- current_time=$(date +%s)
-
- # 计算三个月前的时间戳
- three_months_ago=$((current_time - 3600 * 24 * 90))
-
- # 计算两个月前的时间戳
- two_months_ago=$((current_time - 3600 * 24 * 60))
-
- # 计算一个月前的时间戳
- one_months_ago=$((current_time - 3600 * 24 * 30))
-
- time_range=$(eval echo '$'${4})
-
- echo "更新本地与远端的分支引用"
-
- # 先更新分支引用,确保git branch -r拉取的分支信息,与远端仓库一致(有删除过分支会出现不一致的情况,导致不必要的遍历)
- git remote update origin --prune
-
- echo "更新完毕,开始批量删除目标分支"
-
- branch_all="";
- branch_merged="--merged origin/master";
- branch_no_merged="--no-merged origin/master";
-
- get_branch_rule=$(eval echo '$'${5})
-
-
- # 获取(所有/已合并/未合并)的远程分支,并进行循环处理
- for branch in `git branch -r ${get_branch_rule} | grep -v HEAD` ; do
- # 提取分支名称
- # simple_name=$(echo "$branch" | grep '/' | cut -d'/' -f 2);
-
- simple_name=$(echo "$branch" | sed 's#.*origin/##')
-
- # 排除不需要删除的分支
- excluded_flag="0";
- for excluded_branch in "${excluded_branches[@]}"; do
- if [[ "$simple_name" == "$excluded_branch" ]]; then
- excluded_flag="1";
- break
- fi
- done
-
- # 判断是否满足删除条件
- if [[ $excluded_flag == "0" ]]; then
- if [[ -n $excluded_filter ]]; then
- if [[ "$simple_name" == *"$excluded_filter"* ]]; then
- continue
- fi
- fi
-
- if [[ -n $include_filter ]]; then
- if [[ "$simple_name" != *"$include_filter"* ]]; then
- continue
- fi
- fi
-
-
- # 获取分支最后提交时间
- branch_timestamp=$(git show --format="%at" "$branch" | head -n1)
-
- # 根据实际需要选择 三个月前 $three_months_ago 两个月$two_months_ago 一个月前$one_months_ago 当前$current_time
- if [[ $branch_timestamp -lt $time_range ]]; then
- echo "正在删除分支: $simple_name"
-
- # 删除本地分支
- # git branch -d "$simple_name"
-
- # 删除远程分支
- git push origin --delete "$simple_name"
-
- echo "分支 $simple_name 删除完成"
- echo ""
- fi
- fi
-
- done
-
- echo "清除结束"

"delete-node": "node scripts/inquirerDelBranch.js"
当时一键点击是最省时的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。