文章

Git清理长期未更新的远程分支

长期未更新的分支大多是废弃分支,编写shell脚本一键清理,保持远程仓库分支清爽.

在日常的开发中,代码仓库经过长时间的开发,会遗留大量的废弃分支,甚至有时候达到上百个之多。这些分支大部分是因为某些原因废弃或者是临时测试的分支。根据日常的经验,大概一个月不更新的分支即可视为废弃分支。

废弃分支如果人工一个个的删除非常浪费时间,这种工作最适合编写脚本来做了。下面是一个清理废弃分支的shell脚本,支持自定义设置保护分支和废弃分支的判定时间:

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
#!/bin/bash

# -p 保护分支,默认master/main
protect_branches="main master"

# 可删除分支更新自距今天数
num_days_before=30

while getopts :p:d: opt
do
    case "$opt" in
    p) 
        echo "保护分支:$OPARG"
        protect_branches=$protect_branches" $OPARG"
        ;;
    d) 
        echo "删除$OPARG天未更新的远程分支"
        num_days_before=$OPARG
        ;;
    *) echo "不支持参数: $opt";;
    esac
done

# 获取当前时间戳
current_time=$(date +%s)

# 一个月的时间戳(以秒为单位)
one_month_ago=$((current_time - num_days_before * 24 * 60 * 60))

git fetch --all
# 获取所有远程分支信息
rbranch=$(git branch -r)
IFS_OLD=$IFS
IFS=$'\n'
first=true
branches=""

for line in $rbranch; do
    if $first; then
      first=false
      continue
    fi
    line=$(echo "$line"|tr -d ' ')
    branches="$branches $line"
done

IFS=$IFS_OLD

to_del_branches=""

# 遍历远程分支
for branch in $branches; do

    # 获取分支的最后提交时间戳
    last_commit_time=$(git log -1 --format=%ct "$branch")

    # 如果最后提交时间在一个月前,则删除该分支
    if [[ $last_commit_time -lt $one_month_ago ]]; then
        branch_name=$(echo "$branch" | sed 's/^origin\///')
        is_protect=0
        for b in $protect_branches
        do
            if [ $b = "$branch_name" ]; then
              is_protect=1
            fi
        done
        if [ $is_protect -eq 0 ]; then
            to_del_branches=$to_del_branches" $branch_name"
            if [[ $last_commit_time -gt 0 ]]; then
              update_at=$(date "+%Y-%m-%d %H:%M:%S" -r $last_commit_time)
            fi
            printf "发现可删除分支:%-40s\t更新于%s\n" "$branch_name" "$update_at"
        fi
    fi
done

if [[ -n $to_del_branches ]]; then
    read -p "确认删除这些分支吗?(y/n)" yes
    if [ "$yes" = "y" ] ;then
      total=$(echo $to_del_branches | awk '{print NF}')
      progress=0
      for b in $to_del_branches
      do
        git push origin --delete $b
        # 显示进度条
        ((progress++))
        percentage=$((progress * 100 / total))
        bar=$(printf '[%-50s] %d%%\r' $(printf '%.0s=' $(seq 1 $((percentage * 50 / 100)))) $percentage)
        echo -ne "$bar"
      done
    fi
else
    echo "没有需要删除的远程分支"
fi

通过以下步骤将脚本加入到可执行目录中,并赋予可执行权限:

  • 将脚本保存为文件例如: purge_old_branch.sh
  • 拷贝至usr/local/bin中: sudo cp purge_old_branch.sh /usr/local/bin
  • 赋予可执行权限 sudo chmod a+x /usr/local/bin/purge_old_branch.sh

这样,在要清理的git仓库中执行 purge_old_branch.sh 即可清理旧分支,还可以通过 -p 参数指定要保护的分支 -d 参数指定旧分支判定天数

1
purge_old_branch.sh -p dev -d 60 # 不删除dev分支,设定60天以上为可删除分支
本文由作者按照 CC BY 4.0 进行授权

Comments powered by Disqus.