一、问题引出
在实际的生产当中,无论是 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 日志
分支名
提交者
提交过的文件名
提交过的文件中包含的内容
5.提交注释
- 起始日期,结束日期
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️⃣ 简单示例
版权归原作者 AI蓝月 所有, 如有侵权,请联系我们删除。