-
Notifications
You must be signed in to change notification settings - Fork 1
/
git-health
executable file
·184 lines (177 loc) · 6.34 KB
/
git-health
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
180
181
182
183
184
#!/usr/bin/env zsh
# git-health
# --------------------------------------------------------------------------------------------------
# Description
# -----------
# A simple utility to give a health indication from branches in a repository
# --------------------------------------------------------------------------------------------------
# Usage
# -----
# git health [all|local|remote] --stale --markdown
#
# By default, git health will be run against local branches. You can pass local to only check local
# branches and remote to only check remote branches and all to check all
# branches.
#
# The branches will be sorted by last activity, from the most recently active to the least recent
# active. You can use a dash prefix to invert the order, so git health -all will list all branches
# with the most stale branch on top and the most recent active branch on the bottom
#
# If you pass the --stale option, only stale branches will be listed. By
# default, branches are considered stale if no commit was made to them in the
# past 3 months. You can pass a value to stale, so '--stale "15 days ago"' will
# list branches with no commits in the last 15 days.
#
# Options
# -------
#
# --stale
#
# List only stale branches. By default, stale branches are branches who have no
# commits in the past 3 months. You can pass a value to --stale to change that
# behavior:
#
# git health --stale "15 days ago"
#
# Will consider any branch that has had no commits in the past 15 days to be
# stale. The format is the same as the one used by git-log
#
# --markdown
#
# Outputs a Markdown table with the branch and the last activity date
#
# --slack
#
# Outputs a "table" that can be sent on Slack, since it doesn't support proper
# markdown tables
#
# --------------------------------------------------------------------------------------------------
# Authors
# -------
# Filipe Kiss <[email protected]> http://github.com/filipekiss
# --------------------------------------------------------------------------------------------------
#
_default_ref_format="%(color:yellow)%(refname:short)%(color:reset) %(color:green)%(committerdate:relative)%(color:reset)"
_default_log_format="%C(yellow)%S%C(reset) %C(green)%cr %C(reset)"
_markdown_ref_format="| %(refname:short) | %(committerdate:relative) |"
_markdown_log_format="|%S|%cr|"
_slack_ref_format="*%(refname:short)* (%(committerdate:relative))"
_slack_log_format="*%S* (%cr)"
function hasActivity() {
branches=($(command git for-each-ref --sort="${SORT_ORDER}" ${REF_PATTERN} --format="%(refname:short)"))
[[ -n "${_header:-}" ]] && echo "${_header}"
for branch in $branches;
do;
hasAct=$(git log --date=relative --after="${STALE_DATE}" -1 $branch --)
if [ -z $hasAct ]; then;
command git --no-pager log -1 $branch --format="${_chosen_log_format}" --
fi
done;
}
function updateRemotes() {
command git fetch --all > /dev/null 2>&1
}
function buildCommand() {
local arg
while (( $# > 0 ))
do
arg="$1"
case "$arg" in
local)
[[ -n ${branchOrdered:-} ]] && continue
REF_PATTERN="refs/heads"
SORT_ORDER="committerdate"
branchOrdered="yes"
;;
-local)
[[ -n ${branchOrdered:-} ]] && continue
REF_PATTERN="refs/heads"
SORT_ORDER="-committerdate"
branchOrdered="yes"
;;
remote)
[[ -n ${branchOrdered:-} ]] && continue
REF_PATTERN="refs/remotes"
SORT_ORDER="committerdate"
UPDATE_REMOTES="yes"
branchOrdered="yes"
;;
-remote)
[[ -n ${branchOrdered:-} ]] && continue
REF_PATTERN="refs/remotes"
SORT_ORDER="-committerdate"
UPDATE_REMOTES="yes"
branchOrdered="yes"
;;
all)
[[ -n ${branchOrdered:-} ]] && continue
REF_PATTERN=("refs/remotes" "refs/heads")
SORT_ORDER="committerdate"
UPDATE_REMOTES="yes"
ALL_BRANCHES="yes"
branchOrdered="yes"
;;
-all)
[[ -n ${branchOrdered:-} ]] && continue
REF_PATTERN=("refs/remotes" "refs/heads")
SORT_ORDER="-committerdate"
UPDATE_REMOTES="yes"
ALL_BRANCHES="yes"
branchOrdered="yes"
;;
--markdown)
_header="| Branch | Last updated |\n| -- | -- |"
_chosen_log_format="${_markdown_log_format}"
_chosen_ref_format="${_markdown_ref_format}"
;;
--slack)
_header="*Branch (last activity)*"
_chosen_log_format="${_slack_log_format}"
_chosen_ref_format="${_slack_ref_format}"
;;
--stale=*)
STALE_DATE=$(echo $arg | cut -d '=' -f2)
;;
--stale)
_is_option "$2" && STALE_DATE="3 months ago"
STALE_DATE=${STALE_DATE:-${2:-"3 months ago"}}
;;
--skip-fetch)
SKIP_FETCH="yes"
;;
--*)
# Inexistent dashed option, alert the user
echo "Unrecognized option ${arg}"
;;
-*)
# Inexistent dashed option, alert the user
echo "Unrecognized option ${arg}"
;;
esac
shift
done
if [[ -z ${branchOrdered:-} ]]; then
REF_PATTERN="refs/heads"
SORT_ORDER="committerdate"
branchOrdered="yes"
fi
return 0
}
function _is_option() {
[[ ${1} =~ "--*" ]] && return 0 || return 1
}
function listBranches() {
buildCommand "$@"
_chosen_log_format="${_chosen_log_format:-${_default_log_format}}"
_chosen_ref_format="${_chosen_ref_format:-${_default_ref_format}}"
if [[ "yes" == ${UPDATE_REMOTES:-no} && "no" == ${SKIP_FETCH:-no} ]]; then
updateRemotes;
fi
if [[ -z ${STALE_DATE:-} ]]; then
[[ -n "${_header:-}" ]] && echo "${_header}"
command git for-each-ref --sort="${SORT_ORDER}" ${REF_PATTERN} --format="${_chosen_ref_format}"
else
hasActivity
fi
}
listBranches "$@"