forked from magicmonty/bash-git-prompt
-
Notifications
You must be signed in to change notification settings - Fork 1
/
gitstatus_pre-1.7.10.sh
executable file
·125 lines (105 loc) · 3.33 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
#!/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" | egrep -c "^$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
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_'
unset upstream
fi
fi
if [[ -z "$remote" ]] ; then
remote='.'
fi
if [[ -z "$upstream" ]] ; then
upstream='^'
fi
printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n" \
"$branch" \
"$remote" \
"$upstream" \
$num_staged \
$num_conflicts \
$num_changed \
$num_untracked \
$num_stashed \
$clean
exit