Git分支批量清理利器:自定义命令行插件实战

说在前面

不知道大家平时工作的时候会不会需要经常新建git分支来开发新需求呢?在我这边工作的时候,需求都是以issue的形式来进行开发,每个issue新建一个关联的分支来进行开发,这样可以通过issue看到一个需求完整的开发记录,便于后续需求回顾和需求回退。而我平时本地分支都不怎么清理,这就导致了我这两年来本地分支的数量达到了惊人的361个,所以便开始写了这个可以批量删除分支的命令行工具。

1697987090644.jpg

功能设计

我们希望可以通过命令行命令的方式来进行交互,快速获取本地分支列表及各分支的最后提交时间和合并状态,在控制台选择我们想要删除的分支。

功能实现

1、命令行交互获取相关参数

这里我们使用@jyeontu/j-inquirer模块来完成命令行交互功能,@jyeontu/j-inquirer模块除了支持inquirer模块的所有交互类型,还扩展了文件选择器文件夹选择器多级选择器交互类型,具体介绍可以查看文档:https://www.npmjs.com/package/@jyeontu/j-inquirer

(1)获取操作分支类型

我们的分支分为本地分支和远程分支,这里我们可以选择我们需要操作的分支类型,选择列表为:"本地分支"、"远程分支"、"本地+远程"

(2)获取远程仓库名(remote)

我们可以输入自己git的远程仓库名,默认为origin

(3)获取生产分支名

我们需要判断各分支是否已经合并到生产分支,所以需要输入自己项目的生产分支名,默认为develop

相关代码
const branchListOptions = [{type: "list",message: "请选择要操作的分支来源:",name: "branchType",choices: ["本地分支", "远程分支", "本地+远程"],},{type: "input",message: "请输入远程仓库名(默认为origin):",name: "gitRemote",default: "origin",},{type: "input",message: "请输入生产分支名(默认为develop):",name: "devBranch",default: "develop",},
];
const res = await doInquirer(branchListOptions);

image.png

2、命令行输出进度条

在分支过多的时候,获取分支信息的时间也会较长,所以我们需要在控制台中打印相关进度,避免用户以为控制台卡死了,如下图:

image.png

image.png

3、git操作

(1)获取git本地分支列表

想要获取当前仓库的所有的本地分支,我们可以使用git branch命令来获取:

function getLocalBranchList() {const command = "git branch";const currentBranch = getCurrentBranch();let branch = child_process.execSync(command).toString().replace(trimReg, "").replace(rowReg, "、");branch = branch.split("、").filter((item) => item !== "" && !item.includes("->") && item !== currentBranch);return branch;
}
(2)获取远程仓库分支列表

想要获取当前仓库的所有的远程分支,我们可以使用git ls-remote --heads origin命令来获取,git ls-remote --heads origin 命令将显示远程仓库 origin 中所有分支的引用信息。其中,每一行显示一个引用,包括提交哈希值和引用的全名(格式为 refs/heads/<branch_name>)。

示例输出可能如下所示:

Copy Code
<commit_hash>        refs/heads/master
<commit_hash>        refs/heads/develop
<commit_hash>        refs/heads/feature/xyz

其中,<commit_hash> 是每个分支最新提交的哈希值。

function getRemoteList(gitRemote) {const command = `git ls-remote --heads ${gitRemote}`;let branchList = child_process.execSync(command).toString().replace(trimReg, "").replace(rowReg, "、");branchList = branchList.split("、").filter((item) => item.includes("refs/heads/")).map((branch) => {return gitRemote + "/" + branch.split("refs/heads/")[1];});return branchList;
}
(3)获取各分支详细信息

我们想要在每个分支后面显示该分支最后提交时间和是否已经合并到生产分支,这两个信息可以作为我们判断该分支是否要删除的一个参考。

  • 获取分支最后提交时间
    git show -s --format=%ci <branchName> 命令用于查看 指定 分支最新提交的提交时间。其中,--format=%ci 用于指定输出格式为提交时间。

在 Git 中,git show 命令用于显示某次提交的详细信息,包括作者、提交时间、修改内容等。通过使用 -s 参数,我们只显示提交摘要信息,而不显示修改内容。

git show -s --format=%ci develop 命令将显示 develop 分支最新提交的提交时间。输出格式为 ISO 8601 标准的时间戳,例如 2023-10-22 16:41:47 +0800

function getBranchLastCommitTime(branchName) {try {const command = `git show -s --format=%ci ${branchName}`;const result = child_process.execSync(command).toString();const date = result.split(" ");return date[0] + " " + date[1];} catch (err) {return "未获取到时间";}
}
  • 判断分支是否合并到生产分支
    git branch --contains <branchName> 命令用于查找包含指定分支(<branchName>)的所有分支。

在 Git 中,git branch 命令用于管理分支。通过使用 --contains 参数,我们可以查找包含指定提交或分支的所有分支。

git branch --contains <branchName> 命令将列出包含 <branchName> 的所有分支。输出结果将显示每个分支的名称以及指定分支是否为当前分支。

示例输出可能如下所示:

Copy Codedevelop
* feature/xyzbugfix/123

其中,* 标记表示当前所在的分支,我们只需要判断输出的分支中是否存在生产分支即可:

function isMergedCheck(branch) {try {const command = `git branch --contains ${branch}`;const result = child_process.execSync(command).toString().replace(trimReg, "").replace(rowReg, "、");const mergedList = result.split("、");return mergedList.includes(gitInfoObj.devBranch)? `已合并到${gitInfoObj.devBranch}`: "";} catch (err) {return "未获取到合并状态";}
}
(4)删除选中分支

选完分支后我们就该来删除分支了,删除分支的命令大家应该就比较熟悉了吧

  • git branch -D <branchName>

git branch -D <branchName> 命令用于强制删除指定的分支(<branchName>)。该命令会删除本地仓库中的指定分支,无法恢复已删除的分支。

  • git push <remote> :<branchName>

git push <remote> :<branchName> 命令用于删除远程仓库<remote>中的指定分支(<branchName>)。这个命令通过推送一个空分支到远程仓库的 <branchName> 分支来实现删除操作。

async function doDeleteBranch(branchList) {const deleteBranchList = await getDeleteBranch(branchList);if (!deleteBranchList) return;console.log("正在删除分支");progressBar.run(0);deleteBranchList.forEach((branch, index) => {let command = `git branch -D ${branch}`;if (branch.includes("/")) {const tmp = branch.split("/");command = `git push ${tmp[0]} :${tmp[1]}`;}child_process.execSync(command);progressBar.run(Math.floor(((index + 1) / deleteBranchList.length) * 100));});console.log("");console.log("已删除分支:" + deleteBranchList);
}

image.png

1697995985140.png

1697996057503.jpg

可以看到我们的分支瞬间就清爽了很多。

使用

该工具已经发布到 npm 上,可以直接通过命令npm i -g jyeontu进行安装,安装完后在控制台中输入jyeontu git即可进行操作。

源码

该工具的源码也已经开源,有兴趣的同学可以到Gitee上查看:Gitee地址

公众号

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

说在后面

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/207025.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言练习记录(蓝桥杯练习)(小蓝数点)

目录 小蓝数点 第一题程序的输出结果是&#xff1f;: 第二题下面代码的执行结果是什么&#xff1f;: 第三题下面代码的执行结果是什么&#xff1f;: 第四题关于关系操作符说法错误的是&#xff1f;: 第五题对于下面代码段&#xff0c;y的值为&#xff1f; 第六题sum 21 …

python——第十五天

面向对象和面向对象编程 面向对象编程&#xff1a; C语言是一门面向过程的编程语言&#xff01;&#xff01;&#xff01; 面向对象的编程思想 就是分门别类的一种能力 面向对象的概念 类&#xff1a; 对一类事物的统称 对象&#xff1a; 一类事物中的具体案例 面向对象的…

ArkTS-自定义弹窗

自定义弹窗 通过CustomDialogController类显示自定义弹窗。使用弹窗组件时&#xff0c;可优先考虑自定义弹窗&#xff0c;便于自定义弹窗的样式与内容。 CustomDialogController仅在作为CustomDialog和Component struct的成员变量&#xff0c;且在Component struct内部定义时赋…

Java中的JMX的使用

文章目录 1. 定义和存在的意义2. 架构2.1 Instrumentation2.2 JMX Agent2.3 Remote Management 3. 启动和连接3.1 注册MBean3.2 有两个方式启动JMX Agent3.3 Remote Management(客户端) 4. MBeanServerConnection使用4.1 列出所有的MBean4.2 列出所有的Domain4.3 MBean计数4.4 …

开源vs闭源,处在大模型洪流中,向何处去?

文章目录 一、开源和闭源的优劣势比较1.1 开源优势1.2 闭源的优势 二、开源和闭源对大模型技术发展的影响2.1 数据共享2.2 算法创新2.3 业务拓展2.4 安全性和隐私2.5 社会责任和伦理 三、开源与闭源的商业模式比较3.1 盈利模式3.2 市场竞争3.3 用户生态3.4 创新速度 四&#xf…

【上海大学数字逻辑实验报告】一、基本门电路

一、 实验目的 熟悉TTL中、小规模集成电路的外形、管脚和使用方法&#xff1b;了解和掌握基本逻辑门电路的输入与输出之间的逻辑关系及使用规则。 二、 实验原理 实现基本逻辑运算和常用逻辑运算的单元电路称为逻辑门电路。门电路通常用高电平VH表示逻辑值“1”&#xff0c;…

ubantu配置网卡ip

1.ifconfig查看网卡 2. vi /etc/network/interfaces auto ens33 # 网卡名 iface ens33 inet static # 注意网卡名 address 192.168.43.10 # 配置ip地址 netmask 255.255.255.0 # 掩码 gateway 192.168.43.1 # 网关 3.重启网卡 ifconfig ens33 down ifco…

微服务--06--Sentinel 限流、熔断

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.微服务保护雪崩问题服务保护方案1.1.请求限流1.2.线程隔离1.3.服务熔断 2.Sentinel2.1.介绍和安装官方网站&#xff1a;[https://sentinelguard.io/zh-cn/](https…

每日一练2023.11.30——验证身份【PTA】

题目链接 &#xff1a;验证身份 题目要求&#xff1a; 一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下&#xff1a; 首先对前17位数字加权求和&#xff0c;权重分配为&#xff1a;{7&#xff0c;9&#xff0c;10&#xff0c;5&a…

Unity3D 导出的apk进行混淆加固、保护与优化原理(防止反编译)

Unity3D 导出的apk进行混淆加固、保护与优化原理&#xff08;防止反编译&#xff09; 目录 前言&#xff1a; 准备资料&#xff1a; 正文&#xff1a; 1&#xff1a;打包一个带有签名的apk 2&#xff1a;对包进行反编译 3&#xff1a;使用ipaguard来对程序进行加固 前言&…

redis运维(二十一)redis 的扩展应用 lua(三)

一 redis 的扩展应用 lua redis加载lua脚本文件 ① 调试lua脚本 redis-cli 通过管道 --pipe 快速导入数据到redis中 ② 预加载方式 1、错误方式 2、正确方式 "案例讲解" ③ 一次性加载 执行命令&#xff1a; redis-cli -a 密码 --eval Lua脚本路径 key …

kNN-NER: Named Entity Recognition with Nearest Neighbor Search

原文链接&#xff1a;https://arxiv.org/pdf/2203.17103.pdf 预发表论文 介绍 受到增强式检索方法的启发&#xff0c;作者提出了kNN-NER&#xff0c;通过检索训练集中k个邻居的标签分布来提高模型命名实体识别分类的准确性。该框架能够通过充分利用训练信息来解决样本类别不平衡…

C++:OJ练习(每日练习系列)

编程题&#xff1a; 题一&#xff1a;字符串相加 415. 字符串相加 - 力扣&#xff08;LeetCode&#xff09; 思路一&#xff1a; 第一步&#xff1a;需要获取字符串的两个尾节点下标&#xff1b; 第二步&#xff1a;创建用于记录进位数、获得的字符串的变量&#xff1b; 第…

nginx部署多个vue或react项目

下载nginx(tar.gz) nginx: download(官方地址) 部署nginx # 进入nginx压缩包所在目录 cd /usr/nginx# 解压 tar -zxvf nginx-1.25.3.tar.gz# 安装nginx的相关依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel# 生成Makefile可编译文件 cd /usr/ng…

SQL Sever 基础知识 - 数据查询

SQL Sever 基础知识 - 一、查询数据 一、查询数据第1节 基本 SQL Server 语句SELECT第2节 SELECT语句示例2.1 SELECT - 检索表示例的某些列2.2 SELECT - 检索表的所有列2.3 SELECT - 对结果集进行筛选2.4 SELECT - 对结果集进行排序2.5 SELECT - 对结果集进行分组2.5 SELECT - …

富必达API:一站式无代码开发集成电商平台、CRM和营销系统

一站式无代码开发的连接解决方案 电子商务、客户服务系统以及其它商业应用&#xff0c;是现代企业运营的重要部分。然而&#xff0c;将这些系统进行有效的整合往往需要复杂的API开发&#xff0c;这对很多企业来说是一个巨大的挑战。富必达API以其一站式的无代码开发解决方案&a…

注解方式优雅的实现Redisson分布式锁

1.前言 随着微服务的快速推进&#xff0c;分布式架构也得到蓬勃的发展&#xff0c;那么如何保证多进程之间的并发则成为需要考虑的问题。因为服务是分布式部署模式&#xff0c;本地锁Reentrantlock和Synchnorized就无法使用了&#xff0c;当然很多同学脱口而出的基于Redis的se…

C语言--每日选择题--Day31

第一题 1. 下面程序 i 的值为&#xff08;&#xff09; int main() {int i 10;int j 0;if (j 0)i; elsei--; return 0; } A&#xff1a;11 B&#xff1a;9 答案及解析 B if语句中的条件判断为赋值语句的时候&#xff0c;因为赋值语句的返回值是右操作数&#xff1b; …

【猜数字游戏】用wxPython实现:基本的游戏框架 + 简单的图形用户界面

【猜数字游戏】 写在最前面猜数字游戏 实现【猜数字游戏】安装wxPython全部代码代码解析1. 初始化界面2. 生成随机数3. 处理猜测4. 特殊功能5. 分数计算 游戏小程序呈现结语 写在最前面 看到了一个比较有意思的问题 https://ask.csdn.net/questions/8038039 猜数字游戏 在这…

Linux系统iptables

目录 一. 防火墙简介 1. 防火墙定义 2. 防火墙分类 ①. 网络层防火墙 ②. 应用层防火墙 二. iptables 1. iptables定义 2. iptables组成 ①. 规则表 ②. 规则链 3. iptables格式 ①. 管理选项 ②. 匹配条件 ③. 控制类型 四. 案例说明 1. 查看规则表 2. 增加新…