随机
Enter 搜索 ↑↓ 切换 Esc 清空

git_tag_list

脚本

Git 标签 美化列表

git_tag_list

Git 标签 美化列表

一键脚本

bash <(curl -sL gitee.com/meimolihan/cmdbox/raw/master/sh/git_tag_list.sh) 5 /vol1/1000/GitHub/cmdbox-main
bash <(curl -sL ../sh/git_tag_list.sh) 5 /vol1/1000/GitHub/cmdbox-main
传参方式 命令示例 说明
不传参 脚本.sh 默认显示当前目录最近 3 个标签
指定数量 脚本.sh 5 显示最近 5 个标签
指定目录 脚本.sh /path/to/repo 显示指定 Git 仓库的标签
数量+目录 脚本.sh 5 /path/to/repo 指定显示 5 个标签来自指定目录
目录+数量 脚本.sh /path/to/repo 5 参数顺序可互换

补充说明

该脚本提供 Git 标签信息的美化展示功能,默认显示最近 3 个标签的详细信息(含创建人、创建时间、绑定提交哈希、提交作者、提交说明),将英文星期和月份翻译为中文,以表格形式分栏对齐输出。支持指定显示数量和目标仓库目录。

效果预览

功能特点

注意事项

脚本源码

#!/bin/bash
set -uo pipefail

list_color_init() {
    export gl_hui=$'\033[38;5;59m'
    export gl_hong=$'\033[38;5;9m'
    export gl_lv=$'\033[38;5;10m'
    export gl_huang=$'\033[38;5;11m'
    export gl_lan=$'\033[38;5;32m'
    export gl_bai=$'\033[38;5;15m'
    export gl_zi=$'\033[38;5;13m'
    export gl_bufan=$'\033[38;5;14m'
    export reset=$'\033[0m'
}
list_color_init

break_end() {
    echo -e "${gl_lv}操作完成${gl_bai}"
    echo -e "${gl_bai}按任意键继续 ${gl_hong}.${gl_huang}.${gl_lv}.${gl_bai}\c"
    read -r -n 1 -s -r -p ""
    echo ""
    clear
}

column_if_available() {
    if command -v column &> /dev/null; then
        column -t -s $'\t'
    else
        cat
    fi
}

print_single_tag() {
    local tag="$1"
    echo -e ""
    echo -e "${gl_huang}>>>【Git标签】${gl_lv}${tag}${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    local full_raw
    full_raw=$(git show "${tag}" 2>/dev/null | sed '/^diff --git/Q')
    if [[ -z "${full_raw}" ]]; then
        printf "%s%s\t%s%s\n" "$gl_huang" "提示" "$gl_huang" "标签 ${tag} 读取失败" "$reset" | column_if_available
        return 0
    fi

    echo "${full_raw}" | sed '/^tag '"${tag}"'/d' | awk -v key_color="$gl_lan" -v val_color="$gl_bufan" -v reset="$reset" '
    BEGIN {
        FS=": "; OFS="\t"
        map_key["Tagger"] = "标签创建人"
        map_key["Date"] = "标签创建时间"
        map_key["commit"] = "绑定提交哈希"
        map_key["Author"] = "提交作者"

        map_week["Mon"]="周一"; map_week["Tue"]="周二"; map_week["Wed"]="周三"
        map_week["Thu"]="周四"; map_week["Fri"]="周五"; map_week["Sat"]="周六"; map_week["Sun"]="周日"

        map_month["Jan"]="01月"; map_month["Feb"]="02月"; map_month["Mar"]="03月"; map_month["Apr"]="04月"
        map_month["May"]="05月"; map_month["Jun"]="06月"; map_month["Jul"]="07月"; map_month["Aug"]="08月"
        map_month["Sep"]="09月"; map_month["Oct"]="10"; map_month["Nov"]="11"; map_month["Dec"]="12"

        state = "tag_info"
        desc_flag = 0
        msg_flag = 0
    }

    /^commit [0-9a-f]+/ {
        sub(/^commit /,"",$0)
        print key_color "绑定提交哈希" reset, val_color $0 reset
        state = "commit_info"
        next
    }

    state=="tag_info" && /^Tagger/ {
        print key_color map_key["Tagger"] reset, val_color $2 reset
        desc_flag=0
        next
    }

    state=="tag_info" && /^Date/ {
        raw_dt = $2
        split(raw_dt, dt, " ")
        w=dt[1]; m=dt[2]; day=dt[3]; time=dt[4]; year=dt[5]; zone=dt[6]
        cn_week = w in map_week ? map_week[w] : w
        cn_month = m in map_month ? map_month[m] : m
        cn_dt = year "年" cn_month day "日 " time " " cn_week " " zone
        print key_color map_key["Date"] reset, val_color cn_dt reset
        desc_flag=0
        next
    }

    state=="tag_info" && NF>0 && !/^[A-Za-z]+: / {
        gsub(/^[ \t]+/,"",$0)
        if (desc_flag == 0) {
            print key_color "标签备注" reset, val_color $0 reset
            desc_flag=1
        } else {
            print key_color "" reset, val_color $0 reset
        }
        next
    }

    state=="commit_info" && /^Author/ {
        print key_color map_key["Author"] reset, val_color $2 reset
        msg_flag=0
        next
    }

    state=="commit_info" && /^Date/ { next }

    state=="commit_info" && NF>0 {
        gsub(/^[ \t]+/,"",$0)
        gsub(/update/,"更新",$0)
        if (msg_flag == 0) {
            print key_color "提交说明" reset, val_color $0 reset
            msg_flag=1
        } else {
            print key_color "" reset, val_color $0 reset
        }
        next
    }
    ' | column_if_available
}

list_all_full_tags() {
    local show_count=3
    local target_dir="$PWD"

    for arg in "$@"; do
        if [[ "$arg" =~ ^[0-9]+$ ]]; then
            show_count="$arg"
        else
            target_dir=$(realpath "$arg")
        fi
    done

    local origin_pwd="$PWD"
    if ! cd "$target_dir"; then
        echo -e "${gl_hong}错误:目录 ${target_dir} 不存在或无法进入!${gl_bai}"
        break_end
        return 1
    fi

    clear
    if ! git rev-parse --is-inside-work-tree &>/dev/null; then
        echo -e "${gl_hong}当前目录「${target_dir}」不是Git仓库!${gl_bai}"
        cd "$origin_pwd"
        break_end
        return 0
    fi

    local tag_list
    tag_list=$(git tag 2>/dev/null | sort -t'v' -k2 -nr | head -n"${show_count}")
    local current_dir_name
    current_dir_name=$(basename "$PWD") 

    if [[ -z "${tag_list}" ]]; then
        echo -e ""
        echo -e "${gl_zi}【Git标签】${gl_lv}${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        echo -e "${gl_hong}错误:仓库 ${current_dir_name} 不存在任何Git标签${gl_bai}"
        echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
        cd "$origin_pwd"
        break_end
        return 0
    fi

    echo -e "${gl_zi}>>> ${gl_huang}${current_dir_name} ${gl_zi}项目 ${gl_huang}Git ${gl_zi}标签(展示前 ${gl_lv}${show_count} ${gl_zi}个) ${gl_bai}"
    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"

    while IFS= read -r single_tag; do
        [[ -z "${single_tag}" ]] && continue
        print_single_tag "${single_tag}"
    done <<< "${tag_list}"

    echo -e "${gl_bufan}————————————————————————————————————————————————${gl_bai}"
    cd "$origin_pwd"
    break_end
}

list_all_full_tags "$@"

创建本地脚本

new_script="new_test.sh"

cat > "$new_script" << 'EOF'
#!/bin/bash

# 粘贴脚本源码

EOF

# 保留本地脚本,去掉 rm -f "$new_script"
chmod +x "$new_script" && ./"$new_script" && rm -f "$new_script"

相关命令