blob: c6a4dcfc37777699d764392bb696f790bf8993bc (
plain)
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
|
#!/bin/bash
# Set up symbols
function _symbols() {
# Import colors
_colors_bash "$@"
__ps="$(printf '%b\u7C%s' "${BOLD}${LEMON}" "${RESET}")" # |
__ss="$(printf '%b\u2714' "${BOLD}${CYAN}")" # ✔
__dss="$(printf '%b\u002A' "${BOLD}${RED}")" # ∗
__ahs="$(printf '%b\u2191' "${BOLD}${CYAN}")" # ↑
__bhs="$(printf '%b\u2193' "${BOLD}${RED}")" # ↓
__duphs="$(printf '%b\u25B2' "${BOLD}${YELLOW}")" # ▲
__duplls="$(printf '%b\u25BC' "${BOLD}${RED}")" # ▼
__duus="$(printf '%bdu' "${BOLD}${CYAN}")" # du
__upulls="$(printf '%b\u25BD' "${BOLD}${GREEN}")" # ▽
__sts="$(printf '%b\u2192\u004D' "${BOLD}${CYAN}")" # →M
__usts="$(printf '%b\u2190\u004D' "${BOLD}${RED}")" # ←M
__stusts="$(printf '%b<M>' "${BOLD}${RED}")" # <M>
__uts="$(printf '%b\u003F' "${BOLD}${RED}")" # ?
__nfs="$(printf '%b\u002B' "${BOLD}${CYAN}")" # +
__dfs="$(printf '%bD' "${BOLD}${RED}")" # D
__rns="$(printf '%b\u2387 ' "${BOLD}${RED}")" # ⎇
}
function _get_git_branch() {
# On branches, this will return the branch name
# On non-branches, (no branch)
ref="$(git symbolic-ref HEAD 2> /dev/null | sed -e 's/refs\/heads\///')"
if [[ -n $ref ]]; then
printf '%s' "$ref"
else
printf "(no branch)"
fi
}
function _get_git_progress() {
# Detect in-progress actions (e.g. merge, rebase)
# https://github.com/git/git/blob/v1.9-rc2/wt-status.c#L1199-L1241
git_dir="$(git rev-parse --git-dir)"
# git merge
if [[ -f "$git_dir/MERGE_HEAD" ]]; then
printf " [merge]"
elif [[ -d "$git_dir/rebase-apply" ]]; then
# git am
if [[ -f "$git_dir/rebase-apply/applying" ]]; then
printf " [am]"
# git rebase
else
printf " [rebase]"
fi
elif [[ -d "$git_dir/rebase-merge" ]]; then
# git rebase --interactive/--merge
printf " [rebase]"
elif [[ -f "$git_dir/CHERRY_PICK_HEAD" ]]; then
# git cherry-pick
printf " [cherry-pick]"
fi
if [[ -f "$git_dir/BISECT_LOG" ]]; then
# git bisect
printf " [bisect]"
fi
if [[ -f "$git_dir/REVERT_HEAD" ]]; then
# git revert --no-commit
printf " [revert]"
fi
}
_prompt_is_branch1_behind_branch2 () {
# $ git log origin/master..master -1
# commit 4a633f715caf26f6e9495198f89bba20f3402a32
# Author: Todd Wolfson <todd@twolfson.com>
# Date: Sun Jul 7 22:12:17 2013 -0700
#
# Unsynced commit
# Find the first log (if any) that is in branch1 but not branch2
first_log="$(git log "$1..$2" -1 2> /dev/null)"
# Exit with 0 if there is a first log, 1 if there is not
[[ -n "$first_log" ]]
}
_prompt_branch_exists () {
# List remote branches | # Find our branch and exit with 0 or 1 if found/not found
git branch --remote 2> /dev/null | grep --quiet "$1"
}
_prompt_parse_git_ahead () {
# Grab the local and remote branch
branch="$(_get_git_branch)"
remote="$(git config --get "branch.${branch}.remote" || echo -n "origin")"
remote_branch="$remote/$branch"
# $ git log origin/master..master
# commit 4a633f715caf26f6e9495198f89bba20f3402a32
# Author: Todd Wolfson <todd@twolfson.com>
# Date: Sun Jul 7 22:12:17 2013 -0700
#
# Unsynced commit
# If the remote branch is behind the local branch
# or it has not been merged into origin (remote branch doesn't exist)
if (_prompt_is_branch1_behind_branch2 "$remote_branch" "$branch" || ! _prompt_branch_exists "$remote_branch"); then echo -n "0"; else echo -n "1"; fi
}
_prompt_parse_git_behind() {
# Grab the branch
branch="$(_get_git_branch)"
remote="$(git config --get "branch.${branch}.remote" || echo -n "origin")"
remote_branch="$remote/$branch"
# $ git log master..origin/master
# commit 4a633f715caf26f6e9495198f89bba20f3402a32
# Author: Todd Wolfson <todd@twolfson.com>
# Date: Sun Jul 7 22:12:17 2013 -0700
#
# Unsynced commit
# If the local branch is behind the remote branch
if _prompt_is_branch1_behind_branch2 "$branch" "$remote_branch"; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_dirty() {
# If the git status has *any* changes (e.g. dirty), printf our character
if [[ -n "$(git status --porcelain 2> /dev/null)" ]]; then echo -n '0'; else echo -n '1'; fi
}
# start counter on git
function _git_dirty_count() {
local _dirty_status
local _git_status
_dirty_status="$(_prompt_parse_git_dirty)"
_git_status="$(git status --porcelain 2> /dev/null)"
if [[ "$_dirty_status" == 0 ]]; then
local change_count
change_count="$(echo "$_git_status" | wc -l | tr -d '[:space:]')"
case $change_count in
1) printf '%b\u2022%s' "${BOLD}${GREY}" "$change_count";;
2) printf '%b\u2236%s' "${BOLD}${GREY}" "$change_count";;
3) printf '%b\u2026%s' "${BOLD}${GREY}" "$change_count";;
*) printf '%b\u00BB%s' "${BOLD}${GREY}" "$change_count";;
esac
fi
}
function _git_behind_count() {
local __behind_count
__behind_count="$(git rev-list --left-right --count origin/master...HEAD | cut -f1 2> /dev/null)"
case $__behind_count in
0) echo -n '';;
*) echo -n "$__behind_count";;
esac
}
function _git_ahead_count() {
local __ahead_count
__ahead_count="$(git rev-list --left-right --count origin/master...HEAD | cut -f2 2> /dev/null)"
case $__ahead_count in
0) echo -n '';;
*) echo -n "$__ahead_count";;
esac
}
# ends counter on git
function _prompt_parse_git_untracked() {
local untracked
local evaltask
untracked="$(git status 2>&1 | tee)"
grep -E 'Untracked files:' <<<"$untracked" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_newfile() {
local newfile
local evaltask
newfile="$(git status 2>&1 | tee)"
grep -E 'new file:' <<<"$newfile" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_deleted_file() {
local deleted_file
local evaltask
deleted_file="$(git status 2>&1 | tee)"
grep -E 'deleted:' <<<"$deleted_file" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_renamed() {
local renamed
local evaltask
renamed="$(git status 2>&1 | tee)"
grep -E 'renamed:' <<<"$renamed" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_unstage() {
local unstage
local evaltask
unstage="$(git status 2>&1 | tee)"
grep -E 'not staged' <<<"$unstage" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_stage() {
local stage
local evaltask
stage="$(git status -s 2>&1 | tee)"
grep -E 'M' <<<"$stage" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_is_on_git() {
git rev-parse 2> /dev/null
}
function _prompt_get_git_status() {
_symbols "$@"
# Grab the git dirty and git behind
count_dirty="$(_git_dirty_count)"
count_behind="$(_git_behind_count)"
count_ahead="$(_git_ahead_count)"
dirty_branch="$(_prompt_parse_git_dirty)"
branch_ahead="$(_prompt_parse_git_ahead)"
branch_behind="$(_prompt_parse_git_behind)"
branch_stage="$(_prompt_parse_git_stage)"
branch_unstage="$(_prompt_parse_git_unstage)"
branch_untracked="$(_prompt_parse_git_untracked)"
branch_newfile="$(_prompt_parse_git_newfile)"
branch_deleted_file="$(_prompt_parse_git_deleted_file)"
branch_renamed="$(_prompt_parse_git_renamed)"
# Iterate through all the cases and if it matches, then printf
case ${dirty_branch}${branch_ahead}${branch_behind}${branch_stage}${branch_unstage}${branch_newfile}${branch_untracked}${branch_deleted_file}${branch_renamed} in
111111111) printf '%s' "${__ss}";;
100111111) printf '%s' "${__ps}${__ahs}$count_ahead${__ps}${__bhs}$count_behind";;
110111111) printf '%s%s' "${__upulls}" "$count_behind";;
101111111) printf '%s%s' "${__ahs}" "$count_ahead";;
010111111) printf '%s%s%s' "${__duplls}" "$count_behind" "$count_dirty";;
001111111) printf '%s%s%s' "${__duphs}" "$count_ahead" "$count_dirty";;
000111111) printf '%s%s%s' "${__duus}" "$count_behind-$count_ahead" "$count_dirty";;
000111011) printf '%s%s' "${__ps}${__ahs}$count_ahead${__ps}${__bhs}$count_behind${__ps}${__uts}${__ps}" "$count_dirty" ;;
010111011) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__uts}" "${__ps}$count_dirty";;
010110111) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}" "${__ps}$count_dirty";;
010110011) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__uts}" "${__ps}$count_dirty";;
010100001) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__usts}${__uts}${__dfs}" "${__ps}$count_dirty";;
010000001) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__stusts}${__uts}${__dfs}" "${__ps}$count_dirty";;
010010100) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__dfs}${__rns}" "${__ps}${__sts}${__ps}$count_dirty";;
010010000) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__dfs}${__rns}${__ps}${__uts}" "${__ps}${__sts}${__ps}$count_dirty";;
011001111) printf '%s%s' "${__ps}${__dss}${__stusts}" "$count_dirty";;
011000111) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}" "$count_dirty";;
011001101) printf '%s%s' "${__ps}${__dss}${__stusts}${__dfs}" "$count_dirty";;
011001011) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}" "$count_dirty" ;;
011001001) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}${__dfs}" "$count_dirty";;
011000101) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__dfs}" "$count_dirty";;
011000001) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
011011111) printf '%s%s' "${__ps}${__dss}${__sts}" "$count_dirty";;
011010111) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}" "$count_dirty";;
011010101) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__dfs}" "$count_dirty" ;;
011010001) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
011011011) printf '%s%s' "${__ps}${__dss}${__sts}${__uts}" "$count_dirty";;
011011101) printf '%s%s' "${__ps}${__dss}${__sts}${__dfs}" "$count_dirty";;
011110111) printf '%s%s' "${__ps}${__dss}${__nfs}" "$count_dirty";;
011110011) printf '%s%s' "${__ps}${__dss}${__nfs}${__uts}" "$count_dirty";;
011111011) printf '%s%s' "${__ps}${__dss}${__uts}" "$count_dirty";;
011101001) printf '%s%s' "${__ps}${__dss}${__usts}${__uts}${__dfs}" "$count_dirty";;
011101001) printf '%s%s' "${__ps}${__dss}${__usts}${__dfs}" "$count_dirty";;
011111110) printf '%s%s' "${__ps}${__dss}${__rns}" "$count_dirty";;
011110110) printf '%s%s' "${__ps}${__dss}${__nfs}${__rns}" "$count_dirty";;
011110010) printf '%s%s' "${__ps}${__dss}${__nfs}${__uts}${__rns}" "$count_dirty";;
011010100) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__dfs}${__rns}" "$count_dirty" ;;
011010000) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
011001010) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}${__rns}" "$count_dirty";;
011001000) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}${__dfs}${__rns}" "$count_dirty";;
011000110) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__rns}" "$count_dirty";;
011000010) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}${__rns}" "$count_dirty";;
011000000) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
011000100) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__dfs}${__rns}" "$count_dirty";;
011010010) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}${__rns}" "$count_dirty";;
011011010) printf '%s%s' "${__ps}${__dss}${__sts}${__uts}${__rns}" "$count_dirty";;
011111010) printf '%s%s' "${__ps}${__dss}${__uts}${__rns}" "$count_dirty";;
001001111) printf '%s%s' "${__ps}${__duus}${__stusts}" "$count_dirty";;
001000111) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}" "$count_dirty";;
001001101) printf '%s%s' "${__ps}${__duus}${__stusts}${__dfs}" "$count_dirty";;
001001011) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}" "$count_dirty";;
001001001) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}${__dfs}" "$count_dirty";;
001000101) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__dfs}" "$count_dirty";;
001000001) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
001011111) printf '%s%s' "${__ps}${__duus}${__sts}" "$count_dirty";;
001010111) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}" "$count_dirty" ;;
001010101) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__dfs}" "$count_dirty" ;;
001010001) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
001011011) printf '%s%s' "${__ps}${__duus}${__sts}${__uts}" "$count_dirty";;
001011101) printf '%s%s' "${__ps}${__duus}${__sts}${__dfs}" "$count_dirty";;
001110111) printf '%s%s' "${__ps}${__duus}${__nfs}" "$count_dirty";;
001110011) printf '%s%s' "${__ps}${__duus}${__nfs}${__uts}" "$count_dirty";;
001111011) printf '%s%s' "${__ps}${__duus}${__uts}" "$count_dirty";;
001101001) printf '%s%s' "${__ps}${__duus}${__usts}${__uts}${__dfs}" "$count_dirty";;
001101101) printf '%s%s' "${__ps}${__duus}${__usts}${__dfs}" "$count_dirty";;
001111110) printf '%s%s' "${__ps}${__duus}${__rns}" "$count_dirty";;
001110110) printf '%s%s' "${__ps}${__duus}${__nfs}${__rns}" "$count_dirty";;
001110010) printf '%s%s' "${__ps}${__duus}${__nfs}${__uts}${__rns}" "$count_dirty";;
001010100) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__dfs}${__rns}" "$count_dirty" ;;
001010000) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
001001010) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}${__rns}" "$count_dirty";;
001001000) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}${__dfs}${__rns}" "$count_dirty";;
001000110) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__rns}" "$count_dirty";;
001000010) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}${__rns}" "$count_dirty";;
001000000) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
001000100) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__dfs}${__rns}" "$count_dirty";;
001010010) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}${__rns}" "$count_dirty";;
001011010) printf '%s%s' "${__ps}${__duus}${__sts}${__uts}${__rns}" "$count_dirty";;
001111010) printf '%s%s' "${__ps}${__duus}${__uts}${__rns}" "$count_dirty";;
*) echo -n "${__uts}" ;;
esac
#
# dirty + unpushed = du stage + unstage = <M>
# ∗ ↑ ↓ →M ←M + ? D ⎇
# echo "${dirty_branch}${branch_ahead}${branch_behind}${branch_stage}${branch_unstage}${branch_newfile}${branch_untracked}${branch_deleted_file}${branch_renamed}"
# 0 1 0 1 1 1 0 1 1
}
_prompt_get_git_info() {
# Import colors
_colors_bash "$@"
# Grab the branch
branch="$(_get_git_branch)"
# If there are any branches
if [[ -n $branch ]]; then
# Printf the branch
output="$branch"
# Add on the git status
output="$output$(_prompt_get_git_status "$@")"
# Printf our output
printf '%b%s%b' "${BOLD}${LEMON}" "git:($output" "${BOLD}${LEMON})"
fi
}
__prompt_git() {
if _prompt_is_on_git &> /dev/null; then
echo -n "${BOLD}${WHITE} on $RESET" && \
echo -n "$(_prompt_get_git_info "$@")" && \
echo -n "${BOLD}${RED}$(_get_git_progress)" && \
echo -n "$RESET"
fi
}
|