245 lines
4.2 KiB
Plaintext
245 lines
4.2 KiB
Plaintext
|
##
|
||
|
## Load with `autoload -U zgitinit; zgitinit'
|
||
|
##
|
||
|
|
||
|
typeset -gA zgit_info
|
||
|
zgit_info=()
|
||
|
|
||
|
zgit_chpwd_hook() {
|
||
|
zgit_info_update
|
||
|
}
|
||
|
|
||
|
zgit_preexec_hook() {
|
||
|
if [[ $2 == git\ * ]] || [[ $2 == *\ git\ * ]]; then
|
||
|
zgit_precmd_do_update=1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_precmd_hook() {
|
||
|
if [ $zgit_precmd_do_update ]; then
|
||
|
unset zgit_precmd_do_update
|
||
|
zgit_info_update
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_info_update() {
|
||
|
zgit_info=()
|
||
|
|
||
|
local gitdir="$(git rev-parse --git-dir 2>/dev/null)"
|
||
|
if [ $? -ne 0 ] || [ -z "$gitdir" ]; then
|
||
|
return
|
||
|
fi
|
||
|
|
||
|
zgit_info[dir]=$gitdir
|
||
|
zgit_info[bare]=$(git rev-parse --is-bare-repository)
|
||
|
zgit_info[inwork]=$(git rev-parse --is-inside-work-tree)
|
||
|
}
|
||
|
|
||
|
zgit_isgit() {
|
||
|
if [ -z "$zgit_info[dir]" ]; then
|
||
|
return 1
|
||
|
else
|
||
|
return 0
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_inworktree() {
|
||
|
zgit_isgit || return
|
||
|
if [ "$zgit_info[inwork]" = "true" ]; then
|
||
|
return 0
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_isbare() {
|
||
|
zgit_isgit || return
|
||
|
if [ "$zgit_info[bare]" = "true" ]; then
|
||
|
return 0
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_head() {
|
||
|
zgit_isgit || return 1
|
||
|
|
||
|
if [ -z "$zgit_info[head]" ]; then
|
||
|
local name=''
|
||
|
name=$(git symbolic-ref -q HEAD)
|
||
|
if [ $? -eq 0 ]; then
|
||
|
if [[ $name == refs/(heads|tags)/* ]]; then
|
||
|
name=${name#refs/(heads|tags)/}
|
||
|
fi
|
||
|
else
|
||
|
name=$(git name-rev --name-only --no-undefined --always HEAD)
|
||
|
if [ $? -ne 0 ]; then
|
||
|
return 1
|
||
|
elif [[ $name == remotes/* ]]; then
|
||
|
name=${name#remotes/}
|
||
|
fi
|
||
|
fi
|
||
|
zgit_info[head]=$name
|
||
|
fi
|
||
|
|
||
|
echo $zgit_info[head]
|
||
|
}
|
||
|
|
||
|
zgit_branch() {
|
||
|
zgit_isgit || return 1
|
||
|
zgit_isbare && return 1
|
||
|
|
||
|
if [ -z "$zgit_info[branch]" ]; then
|
||
|
local branch=$(git symbolic-ref HEAD 2>/dev/null)
|
||
|
if [ $? -eq 0 ]; then
|
||
|
branch=${branch##*/}
|
||
|
else
|
||
|
branch=$(git name-rev --name-only --always HEAD)
|
||
|
fi
|
||
|
zgit_info[branch]=$branch
|
||
|
fi
|
||
|
|
||
|
echo $zgit_info[branch]
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
zgit_tracking_remote() {
|
||
|
zgit_isgit || return 1
|
||
|
zgit_isbare && return 1
|
||
|
|
||
|
local branch
|
||
|
if [ -n "$1" ]; then
|
||
|
branch=$1
|
||
|
elif [ -z "$zgit_info[branch]" ]; then
|
||
|
branch=$(zgit_branch)
|
||
|
[ $? -ne 0 ] && return 1
|
||
|
else
|
||
|
branch=$zgit_info[branch]
|
||
|
fi
|
||
|
|
||
|
local k="tracking_$branch"
|
||
|
local remote
|
||
|
if [ -z "$zgit_info[$k]" ]; then
|
||
|
remote=$(git config branch.$branch.remote)
|
||
|
zgit_info[$k]=$remote
|
||
|
fi
|
||
|
|
||
|
echo $zgit_info[$k]
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
zgit_tracking_merge() {
|
||
|
zgit_isgit || return 1
|
||
|
zgit_isbare && return 1
|
||
|
|
||
|
local branch
|
||
|
if [ -z "$zgit_info[branch]" ]; then
|
||
|
branch=$(zgit_branch)
|
||
|
[ $? -ne 0 ] && return 1
|
||
|
else
|
||
|
branch=$zgit_info[branch]
|
||
|
fi
|
||
|
|
||
|
local remote=$(zgit_tracking_remote $branch)
|
||
|
[ $? -ne 0 ] && return 1
|
||
|
if [ -n "$remote" ]; then # tracking branch
|
||
|
local merge=$(git config branch.$branch.merge)
|
||
|
if [ $remote != "." ]; then
|
||
|
merge=$remote/$(basename $merge)
|
||
|
fi
|
||
|
echo $merge
|
||
|
return 0
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_isindexclean() {
|
||
|
zgit_isgit || return 1
|
||
|
if git diff --quiet --cached 2>/dev/null; then
|
||
|
return 0
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_isworktreeclean() {
|
||
|
zgit_isgit || return 1
|
||
|
if [ -z "$(git ls-files --modified)" ]; then
|
||
|
return 0
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_hasuntracked() {
|
||
|
zgit_isgit || return 1
|
||
|
local -a flist
|
||
|
flist=($(git ls-files --others --exclude-standard))
|
||
|
if [ $#flist -gt 0 ]; then
|
||
|
return 0
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_hasunmerged() {
|
||
|
zgit_isgit || return 1
|
||
|
local -a flist
|
||
|
flist=($(git ls-files -u))
|
||
|
if [ $#flist -gt 0 ]; then
|
||
|
return 0
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
zgit_svnhead() {
|
||
|
zgit_isgit || return 1
|
||
|
|
||
|
local commit=$1
|
||
|
if [ -z "$commit" ]; then
|
||
|
commit='HEAD'
|
||
|
fi
|
||
|
|
||
|
git svn find-rev $commit
|
||
|
}
|
||
|
|
||
|
zgit_rebaseinfo() {
|
||
|
zgit_isgit || return 1
|
||
|
if [ -d $zgit_info[dir]/rebase-merge ]; then
|
||
|
dotest=$zgit_info[dir]/rebase-merge
|
||
|
elif [ -d $zgit_info[dir]/.dotest-merge ]; then
|
||
|
dotest=$zgit_info[dir]/.dotest-merge
|
||
|
elif [ -d .dotest ]; then
|
||
|
dotest=.dotest
|
||
|
else
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
zgit_info[dotest]=$dotest
|
||
|
|
||
|
zgit_info[rb_onto]=$(cat "$dotest/onto")
|
||
|
if [ -f "$dotest/upstream" ]; then
|
||
|
zgit_info[rb_upstream]=$(cat "$dotest/upstream")
|
||
|
else
|
||
|
zgit_info[rb_upstream]=
|
||
|
fi
|
||
|
if [ -f "$dotest/orig-head" ]; then
|
||
|
zgit_info[rb_head]=$(cat "$dotest/orig-head")
|
||
|
elif [ -f "$dotest/head" ]; then
|
||
|
zgit_info[rb_head]=$(cat "$dotest/head")
|
||
|
fi
|
||
|
zgit_info[rb_head_name]=$(cat "$dotest/head-name")
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
add-zsh-hook chpwd zgit_chpwd_hook
|
||
|
add-zsh-hook preexec zgit_preexec_hook
|
||
|
add-zsh-hook precmd zgit_precmd_hook
|
||
|
|
||
|
zgit_info_update
|
||
|
|
||
|
# vim:set ft=zsh:
|