Created
September 16, 2013 22:07
-
-
Save whichsteveyp/6587257 to your computer and use it in GitHub Desktop.
Ivan deletes things for no reason.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__gitdir () | |
{ | |
# Note: this function is duplicated in git-completion.bash | |
# When updating it, make sure you update the other one to match. | |
if [ -z "${1-}" ]; then | |
if [ -n "${__git_dir-}" ]; then | |
echo "$__git_dir" | |
elif [ -n "${GIT_DIR-}" ]; then | |
test -d "${GIT_DIR-}" || return 1 | |
echo "$GIT_DIR" | |
elif [ -d .git ]; then | |
echo .git | |
else | |
git rev-parse --git-dir 2>/dev/null | |
fi | |
elif [ -d "$1/.git" ]; then | |
echo "$1/.git" | |
else | |
echo "$1" | |
fi | |
} | |
# stores the divergence from upstream in $p | |
# used by GIT_PS1_SHOWUPSTREAM | |
__git_ps1_show_upstream () | |
{ | |
local key value | |
local svn_remote svn_url_pattern count n | |
local upstream=git legacy="" verbose="" | |
svn_remote=() | |
# get some config options from git-config | |
local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')" | |
while read -r key value; do | |
case "$key" in | |
bash.showupstream) | |
GIT_PS1_SHOWUPSTREAM="$value" | |
if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then | |
p="" | |
return | |
fi | |
;; | |
svn-remote.*.url) | |
svn_remote[ $((${#svn_remote[@]} + 1)) ]="$value" | |
svn_url_pattern+="\\|$value" | |
upstream=svn+git # default upstream is SVN if available, else git | |
;; | |
esac | |
done <<< "$output" | |
# parse configuration values | |
for option in ${GIT_PS1_SHOWUPSTREAM}; do | |
case "$option" in | |
git|svn) upstream="$option" ;; | |
verbose) verbose=1 ;; | |
legacy) legacy=1 ;; | |
esac | |
done | |
# Find our upstream | |
case "$upstream" in | |
git) upstream="@{upstream}" ;; | |
svn*) | |
# get the upstream from the "git-svn-id: ..." in a commit message | |
# (git-svn uses essentially the same procedure internally) | |
local svn_upstream=($(git log --first-parent -1 \ | |
--grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null)) | |
if [[ 0 -ne ${#svn_upstream[@]} ]]; then | |
svn_upstream=${svn_upstream[ ${#svn_upstream[@]} - 2 ]} | |
svn_upstream=${svn_upstream%@*} | |
local n_stop="${#svn_remote[@]}" | |
for ((n=1; n <= n_stop; n++)); do | |
svn_upstream=${svn_upstream#${svn_remote[$n]}} | |
done | |
if [[ -z "$svn_upstream" ]]; then | |
# default branch name for checkouts with no layout: | |
upstream=${GIT_SVN_ID:-git-svn} | |
else | |
upstream=${svn_upstream#/} | |
fi | |
elif [[ "svn+git" = "$upstream" ]]; then | |
upstream="@{upstream}" | |
fi | |
;; | |
esac | |
# Find how many commits we are ahead/behind our upstream | |
if [[ -z "$legacy" ]]; then | |
count="$(git rev-list --count --left-right \ | |
"$upstream"...HEAD 2>/dev/null)" | |
else | |
# produce equivalent output to --count for older versions of git | |
local commits | |
if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)" | |
then | |
local commit behind=0 ahead=0 | |
for commit in $commits | |
do | |
case "$commit" in | |
"<"*) ((behind++)) ;; | |
*) ((ahead++)) ;; | |
esac | |
done | |
count="$behind $ahead" | |
else | |
count="" | |
fi | |
fi | |
# calculate the result | |
if [[ -z "$verbose" ]]; then | |
case "$count" in | |
"") # no upstream | |
p="" ;; | |
"0 0") # equal to upstream | |
p="=" ;; | |
"0 "*) # ahead of upstream | |
p=">" ;; | |
*" 0") # behind upstream | |
p="<" ;; | |
*) # diverged from upstream | |
p="<>" ;; | |
esac | |
else | |
case "$count" in | |
"") # no upstream | |
p="" ;; | |
"0 0") # equal to upstream | |
p=" u=" ;; | |
"0 "*) # ahead of upstream | |
p=" u+${count#0 }" ;; | |
*" 0") # behind upstream | |
p=" u-${count% 0}" ;; | |
*) # diverged from upstream | |
p=" u+${count#* }-${count% *}" ;; | |
esac | |
fi | |
} | |
# __git_ps1 accepts 0 or 1 arguments (i.e., format string) | |
# returns text to add to bash PS1 prompt (includes branch name) | |
__git_ps1 () | |
{ | |
local g="$(__gitdir)" | |
if [ -n "$g" ]; then | |
local r="" | |
local b="" | |
if [ -f "$g/rebase-merge/interactive" ]; then | |
r="|REBASE-i" | |
b="$(cat "$g/rebase-merge/head-name")" | |
elif [ -d "$g/rebase-merge" ]; then | |
r="|REBASE-m" | |
b="$(cat "$g/rebase-merge/head-name")" | |
else | |
if [ -d "$g/rebase-apply" ]; then | |
if [ -f "$g/rebase-apply/rebasing" ]; then | |
r="|REBASE" | |
elif [ -f "$g/rebase-apply/applying" ]; then | |
r="|AM" | |
else | |
r="|AM/REBASE" | |
fi | |
elif [ -f "$g/MERGE_HEAD" ]; then | |
r="|MERGING" | |
elif [ -f "$g/CHERRY_PICK_HEAD" ]; then | |
r="|CHERRY-PICKING" | |
elif [ -f "$g/BISECT_LOG" ]; then | |
r="|BISECTING" | |
fi | |
b="$(git symbolic-ref HEAD 2>/dev/null)" || { | |
b="$( | |
case "${GIT_PS1_DESCRIBE_STYLE-}" in | |
(contains) | |
git describe --contains HEAD ;; | |
(branch) | |
git describe --contains --all HEAD ;; | |
(describe) | |
git describe HEAD ;; | |
(* | default) | |
git describe --tags --exact-match HEAD ;; | |
esac 2>/dev/null)" || | |
b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." || | |
b="unknown" | |
b="($b)" | |
} | |
fi | |
local w="" | |
local i="" | |
local s="" | |
local u="" | |
local c="" | |
local p="" | |
if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then | |
if [ "true" = "$(git rev-parse --is-bare-repository 2>/dev/null)" ]; then | |
c="BARE:" | |
else | |
b="GIT_DIR!" | |
fi | |
elif [ "true" = "$(git rev-parse --is-inside-work-tree 2>/dev/null)" ]; then | |
if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]; then | |
if [ "$(git config --bool bash.showDirtyState)" != "false" ]; then | |
git diff --no-ext-diff --quiet --exit-code || w="*" | |
if git rev-parse --quiet --verify HEAD >/dev/null; then | |
git diff-index --cached --quiet HEAD -- || i="+" | |
else | |
i="#" | |
fi | |
fi | |
fi | |
if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then | |
git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$" | |
fi | |
if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then | |
if [ -n "$(git ls-files --others --exclude-standard)" ]; then | |
u="%" | |
fi | |
fi | |
if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then | |
__git_ps1_show_upstream | |
fi | |
fi | |
local f="$w$i$s$u" | |
printf -- "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p" | |
fi | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment