mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2025-12-26 02:12:33 +01:00
Created a git library to easily create a prompt
__git_ps1 (as in the git contrib file) is available through the newly added library. This library allows to do more elaborated prompts based on : - Current directory type - Current action running in the repository (merge/rebase/...) - Current branch (with relative names or long/short sha1s) - Current index state (file added to working tree/index, etc.) - Status compared to upstream (git only)
This commit is contained in:
parent
0683e4d7bf
commit
a434414cd0
1 changed files with 250 additions and 0 deletions
250
lib/git.zsh
250
lib/git.zsh
|
|
@ -1,3 +1,253 @@
|
|||
GIT_PROMPT_BRANCH_STYLE=""
|
||||
GIT_PROMPT_STASH_STATE="y"
|
||||
GIT_PROMPT_SHA="short"
|
||||
|
||||
function __git_ps1() {
|
||||
local current_dir_status current_repo_status current_branch
|
||||
local current_index_state current_upstream_status
|
||||
local r b w i s u c p f
|
||||
|
||||
current_dir_status="$(_git_current_dir_status)"
|
||||
|
||||
if [ "$current_dir_status" = 'not-git' ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
current_repo_status="$(_git_current_repo_status)"
|
||||
current_branch="$(_git_current_branch "$current_repo_status")"
|
||||
|
||||
r="$(case "${current_repo_status}" in
|
||||
('rebase-interactive')
|
||||
echo '|REBASE-i' ;;
|
||||
('rebase-merge')
|
||||
echo '|REBASE-m' ;;
|
||||
('rebase')
|
||||
echo '|REBASE' ;;
|
||||
('am')
|
||||
echo '|AM' ;;
|
||||
('am-rebase')
|
||||
echo '|AM/REBASE' ;;
|
||||
('merge')
|
||||
echo '|MERGING' ;;
|
||||
('cherry-pick')
|
||||
echo '|CHERRY-PICKING' ;;
|
||||
('bisect')
|
||||
echo '|BISECTING' ;;
|
||||
esac)"
|
||||
b="$current_branch"
|
||||
|
||||
if [ "$current_dir_status" = 'bare' ]; then
|
||||
c="BARE:"
|
||||
elif [ "$current_dir_status" = 'git-dir' ]; then
|
||||
b="GIT_DIR!"
|
||||
elif [ "$current_dir_status" = 'work-tree' ]; then
|
||||
current_index_state="$(_git_current_index_state)"
|
||||
|
||||
if [[ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ]]; then
|
||||
w="$(case "${current_index_state}" in
|
||||
(*'wtmodified'* | *'wtdeleted'*)
|
||||
echo '*' ;;
|
||||
esac)"
|
||||
i="$(case "${current_index_state}" in
|
||||
(*'imodified'* | *'iadded'* | *'ideleted'* | *'irenamed'* | *'icopied'*)
|
||||
echo '+' ;;
|
||||
esac)"
|
||||
fi
|
||||
|
||||
if [[ -n "${GIT_PS1_SHOWSTASHSTATE-}" && "$current_index_state" == *'stashed'* ]]; then
|
||||
s='$'
|
||||
fi
|
||||
|
||||
if [[ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" && "$current_index_state" == *'untracked'* ]]; then
|
||||
u='%%'
|
||||
fi
|
||||
|
||||
if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
|
||||
current_upstream_status="$(_git_current_upstream_status)"
|
||||
p="$(case "$current_upstream_status" in
|
||||
('equal-upstream')
|
||||
echo '=' ;;
|
||||
('ahead-upstream')
|
||||
echo '>' ;;
|
||||
('behind-upstream')
|
||||
echo '<' ;;
|
||||
('diverged-from-upstream')
|
||||
echo '<>' ;;
|
||||
esac)"
|
||||
fi
|
||||
fi
|
||||
|
||||
f="$w$i$s$u"
|
||||
printf "${1:- (%s)}" "$c${b##refs/heads/}${f:+ $f}$r$p"
|
||||
}
|
||||
|
||||
function git_prompt_info() {
|
||||
#Todo rewrite git_prompt_info
|
||||
}
|
||||
|
||||
function _git_current_git_dir() {
|
||||
echo "$(__git_safe rev-parse --git-dir)"
|
||||
}
|
||||
|
||||
function _git_current_dir_status() {
|
||||
local dir_status
|
||||
if [ -z "$(__git_safe rev-parse --git-dir)" ]; then
|
||||
dir_status='not-git'
|
||||
elif [ "$(__git_safe rev-parse --is-bare-repository)" = 'true' ]; then
|
||||
dir_status='bare'
|
||||
elif [ "$(__git_safe rev-parse --is-inside-git-dir)" = 'true' ]; then
|
||||
dir_status='git-dir'
|
||||
elif [ "$(__git_safe rev-parse --is-inside-work-tree)" = 'true' ]; then
|
||||
dir_status='work-tree'
|
||||
else
|
||||
dir_status='unkown'
|
||||
fi
|
||||
|
||||
echo $dir_status
|
||||
}
|
||||
|
||||
function _git_current_repo_status() {
|
||||
local gitRepository=$(_git_current_git_dir)
|
||||
local repo_status
|
||||
|
||||
if [ -f "$gitRepository/rebase-merge/interactive" ]; then
|
||||
repo_status='rebase-interactive'
|
||||
elif [ -d "$gitRepository/rebase-merge" ]; then
|
||||
repo_status='rebase-merge'
|
||||
elif [ -d "$gitRepository/rebase-apply" ]; then
|
||||
if [ -f "$gitRepository/rebase-apply/rebasing" ]; then
|
||||
repo_status='rebase'
|
||||
elif [ -f "$gitRepository/rebase-apply/applying" ]; then
|
||||
repo_status='am'
|
||||
else
|
||||
repo_status='am-rebase'
|
||||
fi
|
||||
elif [ -f "$gitRepository/MERGE_HEAD" ]; then
|
||||
repo_status='merge'
|
||||
elif [ -f "$gitRepository/CHERRY_PICK_HEAD" ]; then
|
||||
repo_status='cherry-pick'
|
||||
elif [ -f "$gitRepository/BISECT_LOG" ]; then
|
||||
repo_status='bisect'
|
||||
else
|
||||
repo_status='normal'
|
||||
fi
|
||||
|
||||
echo $repo_status
|
||||
}
|
||||
|
||||
function _git_current_branch() {
|
||||
local branch
|
||||
local repo_status
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
repo_status="$1"
|
||||
else
|
||||
repo_status="$(_git_current_repo_status)"
|
||||
fi
|
||||
|
||||
if [[ "$repo_status" = 'rebase-interactive' || "$repo_status" = 'rebase-merge' ]]; then
|
||||
branch="$(cat "$(_git_current_git_dir)/rebase-merge/head-name")"
|
||||
else
|
||||
branch="$(__git_safe symbolic-ref HEAD)"
|
||||
if [ -z $branch ]; then
|
||||
if [ "$GIT_PROMPT_BRANCH_STYLE" = 'contains' ]; then
|
||||
branch="$(__git_safe describe --contains HEAD)"
|
||||
elif [ "$GIT_PROMPT_BRANCH_STYLE" = 'branch' ]; then
|
||||
branch="$(__git_safe describe --contains --all HEAD)"
|
||||
elif [ "$GIT_PROMPT_BRANCH_STYLE" = 'describe' ]; then
|
||||
branch="$(__git_safe describe HEAD)"
|
||||
else
|
||||
branch="$(__git_safe describe --tags --exact-match HEAD)"
|
||||
fi
|
||||
fi
|
||||
if [ -z $branch ]; then
|
||||
if [ "$GIT_PROMPT_SHA" = 'long' ]; then
|
||||
branch="$(__git_safe rev-parse HEAD)"
|
||||
else
|
||||
branch="$(__git_safe rev-parse --short HEAD)..."
|
||||
fi
|
||||
fi
|
||||
if [[ -z $branch || $branch = '...' ]]; then
|
||||
branch='unknow'
|
||||
fi
|
||||
fi
|
||||
|
||||
echo $branch
|
||||
}
|
||||
|
||||
function _git_current_index_state(){
|
||||
local index_state=''
|
||||
local index_status="$(__git_safe status --porcelain)"
|
||||
|
||||
#based on git-status 'Short Format' man page
|
||||
if [ -n "$(__git_grep_status "$index_status" 'M.')" ]; then
|
||||
index_state="imodified ${index_state}"
|
||||
fi
|
||||
if [ -n "$(__git_grep_status "$index_status" 'A[ MD]')" ]; then
|
||||
index_state="iadded ${index_state}"
|
||||
fi
|
||||
if [ -n "$(__git_grep_status "$index_status" 'D[ M]')" ]; then
|
||||
index_state="ideleted ${index_state}"
|
||||
fi
|
||||
if [ -n "$(__git_grep_status "$index_status" 'R.')" ]; then
|
||||
index_state="irenamed ${index_state}"
|
||||
fi
|
||||
if [ -n "$(__git_grep_status "$index_status" 'C.')" ]; then
|
||||
index_state="icopied ${index_state}"
|
||||
fi
|
||||
|
||||
if [ -n "$(__git_grep_status "$index_status" '.M')" ]; then
|
||||
index_state="wtmodified ${index_state}"
|
||||
fi
|
||||
if [ -n "$(__git_grep_status "$index_status" '[ MARC]D')" ]; then
|
||||
index_state="wtdeleted ${index_state}"
|
||||
fi
|
||||
|
||||
if [ -n "$(__git_grep_status "$index_status" '??')" ]; then
|
||||
index_state="untracked ${index_state}"
|
||||
fi
|
||||
|
||||
if [[ -n "${GIT_PROMPT_STASH_STATE-}" && -n "$(__git_safe stash list)" ]]; then
|
||||
index_state="stashed ${index_state}"
|
||||
fi
|
||||
|
||||
echo $index_state
|
||||
}
|
||||
|
||||
function _git_current_upstream_status() {
|
||||
#Todo handle svn remotes
|
||||
local upstream_status
|
||||
local upstream='@{upstream}'
|
||||
local differences_count="$(__git_safe rev-list --count --left-right "$upstream"...HEAD)"
|
||||
|
||||
case "$differences_count" in
|
||||
'') # no upstream
|
||||
upstream_status='no-upstream' ;;
|
||||
'0 0') # equal to upstream
|
||||
upstream_status='equal-upstream' ;;
|
||||
'0 '*) # ahead of upstream
|
||||
upstream_status='ahead-upstream' ;;
|
||||
*' 0') # behind upstream
|
||||
upstream_status='behind-upstream' ;;
|
||||
*) # diverged from upstream
|
||||
upstream_status='diverged-from-upstream' ;;
|
||||
esac
|
||||
|
||||
echo $upstream_status
|
||||
}
|
||||
|
||||
function __git_safe(){
|
||||
echo "$(git $* 2>/dev/null)"
|
||||
}
|
||||
|
||||
function __git_grep_status(){
|
||||
echo "$(echo "$1" | grep "^$2 ")"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# get the name of the branch we are on
|
||||
function git_prompt_info() {
|
||||
ref=$(git symbolic-ref HEAD 2> /dev/null) || return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue