Git系列,自定义 git 命令,用 shell 脚本帮助你更好的实现 git 版本控制

news2024/9/20 16:39:21

一、问题引出

在实际的生产当中,无论是 git、小乌龟 git 、idea git 插件,都满足不了我们生产中遇到的一些常见的问题,例如:

  • 工作任务重的时候,手头上可能有若干个分支,每个分支对应着不同的业务,这时我们怎么区分哪个分支对应着哪个任务呢?
  • 我只想看到当前分支是哪个业务的分支,还不想输入烦人的超长命令,怎么办?
  • 我想在任意分支上查询最近六个月来自己提交过哪些文件,改动了多少行,每次改动具体修改了什么,怎么办?
  • ......

二、解决问题的思路

如果你从未有或者几乎没有接触过脚本编程,你或许会很烦那些进行命令操作的人,会觉得他们在装逼,在耍酷,GUI有多爽,多简单,为何非要输那些命令呢?这很正常,我也理解,因为每个人都是这么走过来的,就像你刚学 Linux 和用了三年 Linux 后的你一样;你会发现入门的时候有多么痛苦,但你也会发现,当你真正迈入 Shell 的世界之后,原来曾经的痛苦是值得的!

我以一个过来人的身份告诉你无论是 cmd、bat、linux shell、python shell、vb 还是其他的任何脚本编程语言,他们的价值远远大于你的想象,学会了它们的任何一种,你的工作效率可以最少提高 30% 以上,甚至翻倍!!!下面我说下原因:

  • 一个再好的软件都是针对普罗大众的,不是为私人定制的,它不可能做到让所有人都满意,拿 git 来说,我个人觉得 git 是目前最优秀的版本控制工具,没有之一,曾经有个同事跟我说,学会了 git 你就相当于掌握了项目的时间法则,可以买到后悔药,可以分身,可以不限条件的回忆之前发生的点点滴滴 ......,但是它依旧有它的不足,比如我在 一 提出的问题,我可以毫无疑问的告诉你,我提出的那些问题 git 可以很完美的做到,但是代价也很大——命令太长,需要记忆很多参数,不可复用,下次还得再敲一遍,所以我们需要用我们喜欢的命令,参数来简化它,改造它
  • 任何一款软件,它的 Gui 功能相比于它的 命令模式,至少阉割了 30%,换句话说就是,同一个软件,它在 GUI 上做不了的事,不代表它在 命令行模式下 完不成
  • 如果你已经走入 Shell 世界大门超过两年,你会毫不犹豫的承认在某些特定的情形下 命令行 效率要比 点点点 的 GUI操作 高很多,而这样的情形会每天都出现,这条只有亲身体验才能感受到,所以不要和 GUI 党争论,没有意义

下面我们开门见山的说本篇论文的重点——Git,用到的技术是 Linux Shell,但是注意,Wiindows 操作系统支持,因为 Git Windows 版也提供了 Shell 解析系统——不得不承认,Git 的作者太顶了,不然我们还得将 shell 命令转为 cmd bat 脚本

三、实战操作

1. 为分支添加注释

1️⃣ 在 git 安装目录下的 /etc/gitconfig 配置文件中添加如下代码

[alias]
    # adddesc 可以自定义自己喜欢的名字
    # adddesc.sh 是我们之后需要新建的 shell 脚本
    adddesc = !sh adddesc.sh

2️⃣ 在 git 安装目录下的 usr/bin 目录下新建自己的命令脚本 adddesc.sh,并且编辑如下代码

#! /bin/bash

typeset all_branches=`git branch -a`
typeset obj_branch=$1
typeset obj_desc=$2
typeset is_exist="0"

init_arg(){
	if [ -z "$obj_branch" ] || [ -z "$obj_desc" ]; then
		echo "分支名、分支注释内容不可为空"
		exit 1
	fi

	for curr_branch in $all_branches
	do
		if [ $obj_branch == $curr_branch ]; then
			is_exist="1"
			break
		fi
	done

	if [ "$is_exist" == "0" ]; then
		echo "目标分支不存在, 核实后重试"
		exit 1
	fi

	if [ ${#obj_desc} -le 0 ] || [ ${#obj_desc} -ge 51 ]; then
		echo "注释内容长度(1-50)不合适,请重新配置"
		exit 1
	fi
}


add_desc(){	
	git config branch."$obj_branch".description $obj_desc
}

init_arg
add_desc

3️⃣ 使用命令为自己的分支添加注释

git adddesc <分支名> <分支注释内容>

2. 查看所有分支的注释

1️⃣ 在 git 安装目录下的 /etc/gitconfig 配置文件中添加如下代码

[alias]
    descs = !sh descs.sh

2️⃣ 在 git 安装目录下的 usr/bin 目录下新建自己的命令脚本 descs.sh,并且编辑如下代码

#! /bin/bash

typeset all_branches=$(git for-each-ref --format='%(refname)' refs/heads/ | sed 's|refs/heads/||')

show_descs(){
	for curr_branch in $all_branches
	do
		typeset curr_desc=`git config branch."$curr_branch".description`
		echo "$curr_branch ------> $curr_desc"
	done
}

show_descs

3️⃣ 使用命令查看所有分支的注释

git descs

3. 查看当前分支及其注释

1️⃣ 在 git 安装目录下的 /etc/gitconfig 配置文件中添加如下代码

[alias]
    curr = !sh curr.sh

2️⃣ 在 git 安装目录下的 usr/bin 目录下新建自己的命令脚本 curr.sh,并且编辑如下代码

#! /bin/bash

typeset curr_branch=`git rev-parse --abbrev-ref HEAD`
typeset curr_desc=`git config branch."$curr_branch".description`

show_desc(){
	echo "$curr_branch ------> $curr_desc"
}

show_desc

3️⃣ 使用命令查看当前所在分支及其注释

git curr

4. 自定义 git log 命令

1. 笔者封装的这个命令可谓相当强大,可以根据以下条件筛选 git log 日志

1. 分支名

2. 提交者

3. 提交过的文件名

4. 提交过的文件中包含的内容

5.提交注释

6. 起始日期,结束日期

2. 筛选出来的 git log 日志会显示 谁在什么时候提交了哪些文件,是修改了还是新增了还是删除了,每个文件改动多少行,具体改动内容是什么

3. 可以对比某个分支(或commit点)相对与某个分支(或commit点)多出了哪些提交,这在发版时非常需要,可以防止合并错代码,提交了不必要的提交

1️⃣ 在 git 安装目录下的 /etc/gitconfig 配置文件中添加如下代码

[alias]
    find = !sh find.sh

2️⃣ 在 git 安装目录下的 usr/bin 目录下新建自己的命令脚本 find.sh,并且编辑如下代码

#! /bin/bash
# @author		huhai
# @skill		linxu shell
# @message		git 日志查看脚本

# 命令及参数
typeset command="git log"
typeset argv=" --no-merges --date=short"
typeset pretty=" --pretty=\"%n%n%n%Cred[%cd]%Cgreen<%cn %ce>%C(yellow)[%H]%n%Creset%s\""

# 输出文件路径
typeset outfile="~/Desktop/lanyue.log"

# 入参
typeset branch
typeset username
typeset email
typeset file
typeset context
typeset message
typeset startdate
typeset enddate
typeset basepoint
typeset standpoint
# -a 代表数组
typeset -a all_branches
typeset is_detail="0"
typeset is_out="0"
typeset is_print="0"



# 帮助信息
showhelp(){
	echo "-h [无参]	help:帮助命令"
	echo "-d [无参]	detail:将每次提交的文件修改详细列出"
	echo "-a [无参]	about:将每次提交的文件修改行数列出"
	echo "-o [无参]	out:输出结果到桌面的 lanyue.log 文件"
	echo "-p [无参] print:将完整的命令打印而不是执行"

	echo "\n"

	echo "-b [有参] branch:匹配分支名"
	echo "-u [有参] user:匹配作者"
	echo "-e [有参] email:匹配email"
	echo "-f [有参] file:匹配提交文件"
	echo "-c [有参] context:匹配提交文件所包含的内容"
	echo "-m [有参] message:匹配提交注释"
	echo "-x [有参] (获取 分支|commit 之间的commit历史) 基点"
	echo "-y [有参] (获取 分支|commit 之间的commit历史) 变点"
	echo "-S [有参] Start:匹配开始日期"
	echo "-E [有参] End:匹配结束日期"
	exit 1
}

# 报错信息
errorinfo(){
	echo "出错可能是以下原因:"
	echo "1. 未知参数,请使用 -h 查看帮助信息"
	echo "2. 未给有参子命令提供参数值"
	exit 1
}

# 入参定义
while getopts ":hadopb:u:e:f:c:m:x:y:S:E:" option
do
	case $option in
		b)
			branch=$OPTARG
			;;
		u)
			username=$OPTARG
			;;
		e)
			email=$OPTARG
			;;
		f)
			file=$OPTARG
			;;
		c)
			context=$OPTARG
			;;
		m)
			message=$OPTARG
			;;
		x)
			basepoint=$OPTARG
			;;
		y)
			standpoint=$OPTARG
			;;
		S)
			startdate=$OPTARG
			;;
		E)
			enddate=$OPTARG
			;;
		a)
			is_detail="1"
			;;
		d)
			is_detail="2"
			;;
		o)
			is_out="1"
			;;
		p)
			is_print="1"
			;;
		h)
			showhelp
			;;
		?)
			errorinfo
			;;
	esac
done



# 初始化分支信息
init_branch(){
	# 判断目标分支是否真实存在的标志
	typeset is_exist="0"

	# 如果没有输入分支,则默认当前分支为操作对象
	if [ -z "$branch" ]; then
		branch=`git symbolic-ref --short HEAD`
	fi

	# 判断输入分支是否合法(存在)
	all_branches=`git branch -a`
	for curr_branch in $all_branches
	do
		if [ $curr_branch == $branch ]; then
			is_exist="1"
			break
		fi
	done

	if [ $is_exist == "0" ]; then
		echo "目标分支 [-b 参数] 不存在,请核实后重试"
		exit 1
	fi

	command=$command" "$branch
}

# 初始化比较信息,用于得到 standpoint 相较于 basepoint 多了的提交历史
init_compare(){
	if [ ! -z "$basepoint" ]; then
		if [ -z "$standpoint" ]; then
			standpoint=`git symbolic-ref --short HEAD`
		fi
	fi

	if [ ! -z "$standpoint" ]; then
		if [ -z "$basepoint" ]; then
			basepoint=`git symbolic-ref --short HEAD`
		fi
	fi

	if [ ! -z "$basepoint" ] && [ ! -z "$standpoint" ]; then
		command="git log"
		command=$command" "$basepoint".."$standpoint
	fi
}

# 初始化开始日期信息
init_startdate(){
	if [ ! -z "$startdate" ]; then
		typeset date_type=`echo $startdate | grep -v '[^0-9]' > /dev/null && /dev/null && echo "number" || echo "string"`

		if [ "$date_type" == "string" ]; then
			echo "开始日期不合法,必须为数字类型"
			exit 1
		elif [ "$date_type" == "number" ]; then
			typeset date_length=`echo ${#startdate}`
			if [ "$date_length" -ne 8 ]; then
				echo "开始日期长度不合法,必须为合法8位日期"
				exit 1
			fi
		else
			echo "未知错误,异常退出"
			exit 1
		fi
		
		# 格式化日期
		typeset year=${startdate:0:4}
		typeset month=${startdate:4:2}
		typeset day=${startdate:6:2}

		typeset startdate_final=$year"-"$month"-"$day

		argv=$argv" --after=""$startdate_final"
	fi
}

# 初始化结束日期信息
init_enddate(){
	if [ ! -z "$enddate" ]; then
		typeset date_type=`echo $enddate | grep -v '[^0-9]' > /dev/null && /dev/null && echo "number" || echo "string"`

		if [ "$date_type" == "string" ]; then
			echo "结束日期不合法,必须为数字类型"
			exit 1
		elif [ "$date_type" == "number" ]; then
			typeset date_length=`echo ${#enddate}`
			if [ "$date_length" -ne 8 ]; then
				echo "结束日期长度不合法,必须为合法8位日期"
				exit 1
			fi
		else
			echo "未知错误,异常退出"
			exit 1
		fi
		
		# 格式化日期
		typeset year=${enddate:0:4}
		typeset month=${enddate:4:2}
		typeset day=${enddate:6:2}

		typeset enddate_final=$year"-"$month"-"$day

		argv=$argv" --before=""$enddate_final"
	fi
}

# 初始化 作者 和 email 信息
init_author_email(){
	typeset is_set="0"

	if [ ! -z "$username" ]; then
		argv="$argv"" --committer=""$username"
		is_set="1"
	fi

	if [ "$is_set" == "0" ] && [ ! -z "$email" ]; then
		argv="$argv"" --committer=""$email"
	fi
}

# 是否显示每次提交的详细信息
init_show_detail(){
	if [ "$is_detail" == "1" ]; then
		argv="$argv"" --numstat"
	elif [ "$is_detail" == "2" ]; then
		argv="$argv"" -p"
	else
		argv="$argv"" --name-status"
	fi
}

# 匹配提交文件名
init_commit_file(){
	if [ ! -z "$file" ]; then
		argv="$argv"" --*""$file""*"
	fi
}

# 匹配提交内容
init_commit_context(){
	if [ ! -z "$context" ]; then
		argv="$argv"" -S""\"""$context""\""
	fi
}

# 匹配提交注释
init_commit_message(){
	if [ ! -z "$message" ]; then
		argv="$argv"" --grep ""$message"
	fi
}

# 执行命令
exec_command(){
	if [ "$is_out" == "1" ]; then
		cmd="$command""$argv""$pretty"" > ""$outfile"
	else
		cmd="$command""$argv""$pretty"
	fi

	if [ "$is_print" == "1" ]; then
		echo "$cmd"
	else
		eval "$cmd"
	fi
}



# 调用函数
init_branch
init_compare
init_startdate
init_enddate
init_author_email
init_show_detail
init_commit_file
init_commit_context
init_commit_message
exec_command

3️⃣ 使用命令查看日志

git find [可选参数]

4️⃣ 简单示例

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql面试题汇总

Mysql面试题 文章目录Mysql面试题一 Mysql索引001 Mysql如何实现的索引机制&#xff1f;002 InnoDB索引与MyISAM索引实现的区别是什么&#xff1f;003 一个表中如果没有创建索引&#xff0c;那么还会创建B树吗&#xff1f;004 说一下B树索引实现原理&#xff08;数据结构&#…

妙啊,Python 管道 Pipe 编写代码如此优雅

大家好&#xff0c;今天这篇文章我将详细讲解 Pipe 如何让你的代码更加简洁的方法&#xff0c;喜欢本文点赞支持&#xff0c;欢迎收藏学习&#xff0c;文末提供技术交流群&#xff0c;欢迎畅聊&#xff01; 我们知道 map 和 filter 是两种有效的 Python 方法来处理可迭代对象。…

如何基于YAML设计接口自动化测试框架?看完秒会!

在设计自动化测试框架的时候&#xff0c;我们会经常将测试数据保存在外部的文件&#xff08;如Excel、YAML、CSV&#xff09;或者数据库中&#xff0c;实现脚本与数据解耦&#xff0c;方便后期维护。目前非常多的自动化测试框架采用通过Excel或者YAML文件直接编写测试用例&…

[附源码]计算机毕业设计springboot招聘系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

电子学会2021年6月青少年软件编程(图形化)等级考试试卷(四级)答案解析

青少年软件编程&#xff08;图形化&#xff09;等级考试试卷&#xff08;四级&#xff09; 分数&#xff1a;100.00 题数&#xff1a;24 一、单选题&#xff08;共10题&#xff0c;每题3分&#xff0c;共30分&#xff09; 1. 执行下列程序&#xff0c;输出的结果为…

bert 环境搭建之PytorchTransformer 安装

这两天跑以前的bert项目发现突然跑不了&#xff0c;报错信息如下&#xff1a; Step1 transformer 安装 RuntimeError: Failed to import transformers.models.bert.modeling_bert because of the following error (look up to see its traceback): module signal has no att…

IOT物联网系统架构

主要由 IotCloodServer物网联服务平台&#xff0c; IotAdminWeb物联网管理平台&#xff0c; IotDataProcessing物联网数据平台&#xff0c; IotDeviceGateway物联网边缘网关&#xff0c; IotDeviceToolHepler物联网边缘网关 控制 设备的工具类&#xff0c; IotApp物联网应…

SpringBoot_整合Mybatis

一 导入依赖 <!--整合mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><dependency><group…

ubuntu20.04屏幕亮度无法调节的解决方法->安装 brightness-controller-simple 软件

文章目录一、问题描述二、解决方法参考链接一、问题描述 安装ubunt20.04.5 之后&#xff0c;调节Ubuntu上方的亮度控制条、按快捷键(FnF5、FnF6) 都不能实现调节亮度的功能。 二、解决方法 安装 brightness-controller-simple 软件&#xff0c;利用软件调节亮度。 sudo add…

论文投稿指南——中文核心期刊推荐(计算机技术2)

>>>深度学习Tricks&#xff0c;第一时间送达<<< 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊。下面&#xff0c;简单介绍下什么是中文核心期刊要目总览&#xff1a; 《中文核心期刊要目总…

Web安全专业学习路线

最专业、全面的网络安全学习路线来咯~&#xff08;虽然是网络安全学习路线&#xff0c;但重心还是在Web安全上&#xff09; 展示学习路线之前&#xff0c;建议大家先了解一下这几个问题&#xff0c;既是认清形势&#xff0c;也是认清自我&#xff1a; 为什么要学网络安全&…

期末测试——JavaScript方式练习题

练习目标&#xff1a; 技术简介&#xff1a; js外部引入顺序结构jQuery Dom操作JavaScrip循环技巧JavaScrip数据操作资源地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1VZMGTKj3Aq9Zn6mtee0egw 提取码&#xff1a;1111 关键字&#xff1a; 1、append()&#x…

高分辨率遥感卫星影像在交通方面的应用及高分二号影像获取

高分辨率遥感影像在城市交通领域具有广泛的应用前景&#xff1a;如遥感交通调查、遥感影像地图与电子地图制作、道路工程地质遥感解译、交通安全与知道抗灾救灾、交通事故现场快速勘察、交通需求预测、车辆与车牌视频识别等等。高分辨率影像比如高分二号卫星、高分一号卫星&…

基于蝙蝠算法实现电力系统经济调度(Matlab代码实现)

目录 摘要&#xff1a; 1.蝙蝠优化算法的基本原理&#xff1a; 2.蝙蝠优化算法的流程&#xff1a; 3.仿真实验分析&#xff1a; 摘要&#xff1a; 基于Matalb平台&#xff0c;构建基于蝙蝠活动行为的蝙蝠优化算法&#xff0c;对一个含有6个火电机组的电力系统进行优化调度…

redis6.2(二)Redis的新数据类型、使用java语言操作Redis

redis的安装配置、基本数据类型可以参考: redis6.2&#xff08;一&#xff09;安装、配置、常用数据类型 5、Redis的新数据类型 (1) Bitmaps Redis提供了Bitmaps这个“数据类型”可以实现对位的操作&#xff1a; &#xff08;1&#xff09; Bitmaps本身不是一种数据类型&am…

Spring基础篇:MVC框架整合

MVC框架整合 MVC框架整合思想 搭建Web运行环境 在Project structor当中进行创建一个maven项目&#xff0c;使用maven-archetype-webapp这个模式来创建maven项目&#xff08;使用这种模板创建项目的好处就是好多东西都给你搭建好了。&#xff09;&#xff0c;项目下Src>mai…

12月03日(第五天)

case 后面必须是常量或者字面量&#xff0c;swtich&#xff08;表达式),表达式可以是short&#xff0c;int,byte,char或者字符串&#xff0c;每个case要注意break语句&#xff0c; switch case的使用&#xff0c;stream流操作对象是数组或集合&#xff0c;第一步获取源数据&…

mysql基础部分第一次复习(9-18章)

子查询 SELECT last_name,salary FROM employees WHERE salary > ( SELECT salary FROM employees WHERE last_name Abel );SELECT department_id, MIN(salary) FROM employees GROUP BY department_id HAVING MIN(salary) > (SELECT MIN(salary) FROM employees WHERE…

JavaScript -- 09. 内置对象的介绍

文章目录内置对象1 解构赋值1.1 保留默认值1.2 接受剩余的所有参数1.3 对函数执行结果解构1.4 交换两个变量的值1.5 二维数组结构2 对象的解构2.1 声明对象同时解构对象2.2 先声明再解构2.3 解构不存在的属性2.4 设置解构别名2.5 设置解构默认值3 对象的序列化3.1 对象的序列化…

【OpenCV-Python】教程:3-15 分水岭图像分割

OpenCV Python 分水岭图像分割 【目标】 学习使用分水岭方法进行基于标记的图像分割cv2.watershed() 【理论】 任何灰度图像都可以被视为地形表面&#xff0c;其中高强度表示山峰和丘陵&#xff0c;而低强度表示山谷&#xff0c;。你开始用不同颜色的水&#xff08;标签&am…