0%

git diff显示行号

问题

git是一个非常好用,也非常多人在用的代码版本管理工具,但是当我们使用git diff 命令查看,比较当前代码和分支代码差异的时候发现左边没有显示行号,当发现有问题需要修改代码这非常的不便于我们查找和修改。

环境

OS: Centos8.5

Git: 2.27.0

效果

image-20231227101633029

代码

  • /bin/目录下创建一个脚本git-diff-lines并执行命令chmod +x /bin/git-diff-lines给于执行权限。该脚本可以在左侧显示文件名和差异的行号。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash

# 函数:处理 git diff 输出,提取文件名、行号以及差异内容
# 将空格替换为 '.',将制表符替换为 '→'
diff-lines() {
local path= # 当前处理的文件路径
local line= # 当前处理的行号
local esc=$'\033' # ANSI 转义序列的前缀

IFS=''
while read -r; do
# 跳过原始文件路径行
if [[ $REPLY =~ ---\ (a/)?.* ]]; then
continue
# 提取新文件路径行并获取文件名
elif [[ $REPLY =~ \+\+\+\ (b/)?([^[:blank:]$esc]+).* ]]; then
path=$(basename "${BASH_REMATCH[2]}")
continue
# 提取并设置更改的行号
elif [[ $REPLY =~ @@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@.* ]]; then
line=${BASH_REMATCH[2]}
continue
# 对于差异行(添加/删除/无更改),输出文件名、行号和内容
elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then
# 将制表符替换为 '→',空格替换为 '.'
local modifiedLine=$(echo "$REPLY" | sed -e 's/ /./g' -e 's/\t/→/g')
echo "$path:$line: $modifiedLine"
# 只有在非删除行时行号递增
if [[ ${BASH_REMATCH[2]} != '-' ]]; then
((line++))
fi
fi
done
}

# 根据是否提供了文件名参数来调用 git diff
if [ -n "$1" ]; then
git diff -U0 --color=always -- "$1" | diff-lines
else
git diff -U0 --color=always | diff-lines
fi
  • 创建一个myGit脚本放在/bin/目录下,并执行命令chmod +x /bin/myGit给于执行权限。

    (1)重定向 git diff 命令

    (2)重定向 git clean 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/bash

readonly OPT_ABORT_LOG="Operation aborted."

#####################################################
function INFO_LOG()
{
if [ ! -z "$1" ];then
echo -e "$1"
fi
}

function INFO_LOG_N()
{
if [ ! -z "$1" ];then
echo -n "$1"
fi
}

function IS_YES_OR_NO()
{
while true;do
INFO_LOG_N "Is this ok (Y/N):"
read answer
answer=$(echo "$answer" |tr '[:upper:]' '[:lower:]')
if [[ "$answer" == "y" ]];then
break
elif [[ "answer" == "n" ]];then
INFO_LOG "$OPT_ABORT_LOG"
exit 1
else
INFO_LOG "Invalid input. Please enter Y or N."
fi
return 0
}
#####################################################

# 检查是否有任何参数传递给脚本
if [ $# -eq 0 ]; then
# 没有参数,直接调用原始的 git 命令
git
exit
fi

# 检查第一个参数是否为 'diff'
if [ "$1" = "diff" ]; then
# 如果是 'git diff',则调用你的自定义命令
git-diff-lines "${@:2}"
elif [ "$1" = "clean" ]; then
# 列出 git clean 将要删除的文件
cd $(git rev-parse --show-toplevel) && git clean -nfd && cd - >/dev/null 2>&1
IS_YES_OR_NO
if [ $? -eq 0 ];then
# 删除 untracked 的文件
cd $(git rev-parse --show-toplevel) && git clean -fd && cd - >/dev/null 2>&1
fi
else
# 否则,调用原始的 git 命令
git "$@"
fi
  • 修改/root/.bashrc文件,将git命令使用alias重定义。
1
alias git='myGit'

reference

[1] https://blog.csdn.net/TAlice/article/details/117533318

[2] https://blog.csdn.net/uhippo/article/details/46365737

小主,路过打个赏再走呗~