-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit-als.sh
More file actions
100 lines (92 loc) · 3.39 KB
/
git-als.sh
File metadata and controls
100 lines (92 loc) · 3.39 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
# =============================================================================
# @Function: git-als (Git Alias Lister - High Performance)
# @Description:
# A high-performance Git alias manager optimized for Windows (MSYS2/Git Bash)
# and macOS. Solves the bottleneck of process forking on Windows by offloading
# string processing and logic to a single GNU Awk (gawk) pipeline.
#
# @Logic:
# - Grouping:
# - Function aliases (!f() {...}) -> Grouped by alias name prefix.
# - Git commands (!git ... or git ...) -> Grouped by first subcommand.
# - Shell commands (!) -> Grouped under 'Other'.
# - Performance: O(n) streaming via gawk, constant (3) subshells.
# - Features: Multi-keyword AND filtering, case-insensitive highlighting,
# and standardized A4-friendly output formatting.
#
# @Requirements:
# - GNU Awk (gawk) 5.0+
# - macOS: brew install gawk
# - Windows: Pre-installed with Git Bash (MSYS2)
#
# @Usage:
# gals [filter_keyword1] [filter_keyword2] ...
# =============================================================================
git-als() {
local search_terms="$*"
# Ensure clean output and handle 'gawk' vs 'awk' naming
local awk_cmd="gawk"
if ! command -v gawk &> /dev/null; then
# Fallback to awk for Windows as it is typically gawk
awk_cmd="awk"
fi
# 直接调用 git config 并通过管道传给 awk
git config --get-regexp '^alias\.' | sort -f | awk -v terms="$search_terms" '
BEGIN {
# 颜色代码
GREEN = "\033[92m"; YELLOW = "\033[93m"; RESET = "\033[0m";
split(tolower(terms), filter_array, " ");
has_filter = (terms != "");
}
{
# 1. 解析 alias.name 和 command
match($0, /^alias\.([^[:space:]]+)[[:space:]]*(.*)$/, m);
name = m[1]; cmd = m[2];
sub(/\r$/, "", cmd); # 兼容 CRLF
# 2. 确定分组 (Logic: 提取命令首词或子命令)
if (cmd ~ /^!/) {
if (cmd ~ /^!f\(\)/) {
grp = (name ~ /-/) ? substr(name, 1, index(name, "-")-1) : name;
} else if (cmd ~ /^!git / || cmd ~ /^!sh -c .*git /) {
split(cmd, parts, " ");
for (i in parts) if (parts[i] != "git" && parts[i] != "!git" && parts[i] != "!sh" && parts[i] != "-c") {
grp = parts[i]; break;
}
if (grp ~ /-/) grp = substr(grp, 1, index(grp, "-")-1);
} else { grp = "Other"; }
} else {
split(cmd, parts, " ");
grp = parts[1];
if (grp ~ /-/) grp = substr(grp, 1, index(grp, "-")-1);
}
if (!grp) grp = "Other";
# 3. 过滤逻辑 (AND 逻辑)
match_all = 1;
if (has_filter) {
low_name = tolower(name); low_cmd = tolower(cmd);
for (i in filter_array) {
if (index(low_name, filter_array[i]) == 0 && index(low_cmd, filter_array[i]) == 0) {
match_all = 0; break;
}
}
}
# 4. 存储与输出
if (match_all) {
if (grp != last_grp) {
if (last_grp != "") printf "\n";
printf "%s%s%s\n", GREEN, grp, RESET;
last_grp = grp;
}
# 高亮处理
out_name = name; out_cmd = cmd;
if (has_filter) {
for (i in filter_array) {
gsub(filter_array[i], YELLOW "&" RESET, out_name);
gsub(filter_array[i], YELLOW "&" RESET, out_cmd);
}
}
printf " %-15s %s\n", out_name, out_cmd;
}
}'
}
alias gals=git-als