-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmygst
More file actions
179 lines (155 loc) · 5.77 KB
/
mygst
File metadata and controls
179 lines (155 loc) · 5.77 KB
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/bin/bash
# 默认值
MAX_DEPTH=99
SHOW_HELP=0
TARGET_DIR="."
STATUS_OPTIONS=""
# 帮助信息
show_help() {
cat << HELP
Usage: $(basename $0) [-d depth] [-o options] [-h] [directory]
显示指定目录下所有 git 仓库的 status 信息(支持分页和颜色显示)
Options:
-d depth 设置查找 git 仓库的最大深度 (默认: 无限递归)
深度从目标目录开始计数,-d 1 只查找目标目录本身
-o options 传递给 git status 的选项 (例如: -s, -b, --porcelain 等)
可以传递多个选项,用引号包裹: -o "-s -b"
-h 显示此帮助信息
Arguments:
directory 要搜索的目录 (默认: 当前目录 .)
Examples:
$(basename $0) # 查找当前目录下所有 git 仓库的 status
$(basename $0) components # 查找 components 目录下所有 git 仓库的 status
$(basename $0) -d 2 . # 只查找当前目录深度 2 以内的 git 仓库
$(basename $0) -o "-s" # 使用短格式显示
$(basename $0) -o "-s -b" # 短格式 + 分支信息
$(basename $0) -o "--porcelain" # 使用 porcelain 格式
$(basename $0) -d 1 -o "-s" apps # 结合深度和 status 选项
常用 git status 选项:
-s, --short 使用短格式输出
-b, --branch 显示分支信息(配合 -s 使用)
--porcelain 机器可读格式
--porcelain=v2 机器可读格式(v2)
-u, --untracked-files 显示未跟踪文件
--ignored 显示被忽略的文件
-v, --verbose 显示详细的 diff 信息
-vv 显示更详细的 diff 信息
注意:
- 输出会自动分页显示(类似 less)
- 使用方向键或 j/k 滚动,q 退出
- 颜色会自动保留
- 支持 git 子模块检查
HELP
}
# 解析参数
while getopts "d:o:h" opt; do
case $opt in
d)
MAX_DEPTH=$OPTARG
# 验证参数是否为数字
if ! [[ "$MAX_DEPTH" =~ ^[0-9]+$ ]]; then
echo "错误: -d 参数必须是正整数" >&2
show_help
exit 1
fi
;;
o)
STATUS_OPTIONS="$OPTARG"
;;
h)
show_help
exit 0
;;
?)
show_help
exit 1
;;
esac
done
# 获取位置参数(目录)
shift $((OPTIND - 1))
if [ $# -gt 0 ]; then
TARGET_DIR="$1"
# 验证目录是否存在
if [ ! -d "$TARGET_DIR" ]; then
echo "错误: 目录 '$TARGET_DIR' 不存在" >&2
exit 1
fi
fi
# 临时文件存储所有 status 输出
TEMP_OUTPUT=$(mktemp)
trap "rm -f $TEMP_OUTPUT" EXIT
# 处理单个仓库的函数
process_repo() {
local work_tree="$1"
local is_submodule="$2"
(
cd "$work_tree"
# 检查是否有任何改动
if [ -z "$(git status --porcelain)" ]; then
# 没有任何改动,跳过此仓库
exit 0
fi
# 格式化标题行(复用 mygd 的格式)
terminal_width=$(tput cols)
echo_len=$(printf "%d\n" 120 $terminal_width | sort -n | head -1)
# 获取分支名(如果可能)
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "no commits")
# 如果是子模块,添加标记
if [ "$is_submodule" = "true" ]; then
original_str=" $work_tree ($branch) [SUBMODULE] "
else
original_str=" $work_tree ($branch) "
fi
# 计算原始字符串的长度
original_len=${#original_str}
# 计算需要补全的等号字符数
padding_len=$(($echo_len - $original_len))
# 在两侧补全等号字符
printf '\033[1;33m=%.0s' $(seq 1 $((padding_len/2)))
echo -n "$original_str"
printf '=%.0s' $(seq 1 $((padding_len/2)))
[ $((padding_len%2)) -eq 1 ] && printf '=' # 如果需要补全的字符数为奇数,则在右侧再补一个等号
printf '\033[0m'
echo # 换行
# 输出 status(保留颜色)
# 如果用户指定了选项,使用用户选项;否则使用默认的短格式
if [ -n "$STATUS_OPTIONS" ]; then
git -c color.status=always status $STATUS_OPTIONS
else
git -c color.status=always status --short
fi
echo # 仓库之间添加空行分隔
)
}
# 查找并处理每个 git 仓库
find "$TARGET_DIR" -maxdepth $MAX_DEPTH -type d -name .git | sort | while read git_dir; do
work_tree=$(dirname "$git_dir")
# 处理主仓库
process_repo "$work_tree" "false"
# 检查并处理子模块
if [ -f "$work_tree/.gitmodules" ]; then
(
cd "$work_tree"
# 获取所有子模块路径
git config --file .gitmodules --get-regexp path | while read key submodule_path; do
# 提取子模块路径(去除 'submodule.xxx.path' 前缀)
submodule_path=$(echo "$submodule_path" | awk '{print $1}')
submodule_full_path="$work_tree/$submodule_path"
# 检查子模块是否已初始化
if [ -d "$submodule_full_path/.git" ] || [ -f "$submodule_full_path/.git" ]; then
process_repo "$submodule_full_path" "true"
fi
done
)
fi
done > "$TEMP_OUTPUT"
# 使用 less 分页显示(保留颜色)
if [ -s "$TEMP_OUTPUT" ]; then
# -R: 保留 ANSI 颜色
# -F: 如果内容少于一屏,直接显示不分页
# -X: 退出后保留输出在终端
less -RFX "$TEMP_OUTPUT"
else
echo "未在任何 git 仓库中发现改动。"
fi