-
Notifications
You must be signed in to change notification settings - Fork 967
/
gitstatus_pre-1.7.10.sh
executable file
·139 lines (119 loc) · 3.88 KB
/
gitstatus_pre-1.7.10.sh
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
#!/usr/bin/env bash
# -*- coding: UTF-8 -*-
# gitstatus.sh -- produce the current git repo status on STDOUT
# Functionally equivalent to 'gitstatus.py', but written in bash (not python).
#
# Alan K. Stebbens <aks@stebbens.org> [http://github.com/aks]
# helper functions
count_lines() { echo "${1}" | grep -Ec "^${2}" ; }
all_lines() { echo "${1}" | grep -v "^$" | wc -l ; }
if [[ -z "${__GIT_PROMPT_DIR-}" ]]; then
SOURCE="${BASH_SOURCE[0]}"
while [[ -h "${SOURCE}" ]]; do
DIR="$( cd -P "$( dirname "${SOURCE}" )" && pwd )"
SOURCE="$(readlink "${SOURCE}")"
[[ "${SOURCE}" != /* ]] && SOURCE="${DIR}/${SOURCE}"
done
__GIT_PROMPT_DIR="$( cd -P "$( dirname "${SOURCE}" )" && pwd )"
fi
if [[ "${__GIT_PROMPT_WITH_USERNAME_AND_REPO}" == "1" ]]; then
# returns "user/repo" from remote.origin.url git variable
#
# supports urls:
# https://user@bitbucket.org/user/repo.git
# https://github.com/user/repo.git
# git@github.com:user/repo.git
#
remote_url=$(git config --get remote.origin.url | sed 's|^.*//||; s/.*@//; s/[^:/]\+[:/]//; s/.git$//')
else
remote_url='.'
fi
gitsym=$( git symbolic-ref HEAD 2>/dev/null )
#If exit status OK, we have a branch
if [[ "${?}" == 0 ]]; then
# the current branch is the tail end of the symbolic reference
branch="${gitsym##refs/heads/}" # get the basename after "refs/heads/"
fi
gitstatus=$( git diff --name-status 2>&1 )
# if the diff is fatal, exit now
if [[ "${?}" != 0 ]]; then exit 0; fi
staged_files=$( git diff --staged --name-status )
num_changed=$(( $( all_lines "${gitstatus}" ) - $( count_lines "${gitstatus}" U ) ))
num_conflicts=$( count_lines "${staged_files}" U )
num_staged=$(( $( all_lines "${staged_files}" ) - num_conflicts ))
num_untracked=$( git ls-files --others --exclude-standard $(git rev-parse --show-cdup) | wc -l )
num_stashed=0
if [[ "${__GIT_PROMPT_IGNORE_STASH}" != "1" ]]; then
stash_file="$( git rev-parse --git-dir )/logs/refs/stash"
if [[ -e "${stash_file}" ]]; then
while IFS='' read -r wcline || [[ -n "${wcline}" ]]; do
((num_stashed++))
done < "${stash_file}"
fi
fi
clean=0
if (( num_changed == 0 && num_staged == 0 && num_untracked == 0 && num_stashed == 0 && num_conflicts == 0 )) ; then
clean=1
fi
remote=""
upstream=""
if [[ -z "${branch-}" ]]; then
tag=$( git describe --tags --exact-match 2>/dev/null )
if [[ -n "${tag}" ]]; then
branch="${tag}"
else
branch="_PREHASH_$( git rev-parse --short HEAD )"
fi
else
remote_name=$( git config "branch.${branch}.remote" )
if [[ -n "$remote_name" ]]; then
merge_name=$( git config "branch.${branch}.merge" )
else
remote_name='origin'
merge_name="refs/heads/${branch}"
fi
if [[ "${remote_name}" == '.' ]]; then
remote_ref="${merge_name}"
else
remote_ref="refs/remotes/${remote_name}/${merge_name##refs/heads/}"
fi
# detect if the local branch have a remote tracking branch
upstream=$( git rev-parse --abbrev-ref "${branch}"@{upstream} 2>&1 )
if [[ "${?}" == 0 ]]; then
# get the revision list, and count the leading "<" and ">"
revgit=$( git rev-list --left-right "${remote_ref}...HEAD" 2>/dev/null )
if [[ "${?}" == 0 ]]; then
num_revs=$( all_lines "${revgit}" )
num_ahead=$( count_lines "${revgit}" "^>" )
num_behind=$(( num_revs - num_ahead ))
if (( num_behind > 0 )) ; then
remote="${remote}_BEHIND_${num_behind}"
fi
if (( num_ahead > 0 )) ; then
remote="${remote}_AHEAD_${num_ahead}"
fi
fi
else
remote='_NO_REMOTE_TRACKING_'
remote_url='.'
unset upstream
fi
fi
if [[ -z "${remote:+x}" ]] ; then
remote='.'
fi
if [[ -z "${upstream:+x}" ]] ; then
upstream='^'
fi
printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n" \
"${branch}" \
"${remote}" \
"${remote_url}" \
"${upstream}" \
"${num_staged}" \
"${num_conflicts}" \
"${num_changed}" \
"${num_untracked// /}" \
"${num_stashed}" \
"${clean}"
exit