Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Ohmyzsh
Commits
daabe2a0
Commit
daabe2a0
authored
Aug 30, 2015
by
Robby Russell
Browse files
Merge pull request #4205 from mcornella/fix-git-prompt-plugin
Fix git-prompt plugin
parents
c10d5c8b
9121f3e9
Changes
2
Show whitespace changes
Inline
Side-by-side
plugins/git-prompt/git-prompt.plugin.zsh
View file @
daabe2a0
# ZSH Git Prompt Plugin from:
# http://github.com/olivierverdier/zsh-git-prompt
#
export
__GIT_PROMPT_DIR
=
$ZSH
/plugins/git-prompt
# Allow for functions in the prompt.
setopt PROMPT_SUBST
__GIT_PROMPT_DIR
=
"
${
0
:A:h
}
"
## Enable auto-execution of functions.
typeset
-ga
preexec_functions
typeset
-ga
precmd_functions
typeset
-ga
chpwd_functions
# Append git functions needed for prompt.
preexec_functions+
=
'preexec_update_git_vars'
precmd_functions+
=
'precmd_update_git_vars'
chpwd_functions+
=
'chpwd_update_git_vars'
## Hook function definitions
function
chpwd_update_git_vars
()
{
update_current_git_vars
}
## Function definitions
function
preexec_update_git_vars
()
{
case
"
$2
"
in
git
*
)
git
*
|
hub
*
|
gh
*
|
stg
*
)
__EXECUTED_GIT_COMMAND
=
1
;;
esac
}
function
precmd_update_git_vars
()
{
if
[
-n
"
$__EXECUTED_GIT_COMMAND
"
]
;
then
if
[
-n
"
$__EXECUTED_GIT_COMMAND
"
]
||
[
!
-n
"
$ZSH_THEME_GIT_PROMPT_CACHE
"
]
;
then
update_current_git_vars
unset
__EXECUTED_GIT_COMMAND
fi
}
function
chpwd_update_git_vars
()
{
update_current_git_vars
}
chpwd_functions+
=(
chpwd_update_git_vars
)
precmd_functions+
=(
precmd_update_git_vars
)
preexec_functions+
=(
preexec_update_git_vars
)
## Function definitions
function
update_current_git_vars
()
{
unset
__CURRENT_GIT_STATUS
local
gitstatus
=
"
$__GIT_PROMPT_DIR
/gitstatus.py"
_GIT_STATUS
=
`
python
${
gitstatus
}
`
__CURRENT_GIT_STATUS
=(
"
${
(f)_GIT_STATUS
}
"
)
_GIT_STATUS
=
$(
python
${
gitstatus
}
2>/dev/null
)
__CURRENT_GIT_STATUS
=(
"
${
(@s
:
:
)_GIT_STATUS
}
"
)
GIT_BRANCH
=
$__CURRENT_GIT_STATUS
[
1]
GIT_AHEAD
=
$__CURRENT_GIT_STATUS
[
2]
GIT_BEHIND
=
$__CURRENT_GIT_STATUS
[
3]
GIT_STAGED
=
$__CURRENT_GIT_STATUS
[
4]
GIT_CONFLICTS
=
$__CURRENT_GIT_STATUS
[
5]
GIT_CHANGED
=
$__CURRENT_GIT_STATUS
[
6]
GIT_UNTRACKED
=
$__CURRENT_GIT_STATUS
[
7]
}
function
prompt_git_info
()
{
git_super_status
()
{
precmd_update_git_vars
if
[
-n
"
$__CURRENT_GIT_STATUS
"
]
;
then
echo
"(%{
${
fg
[red]
}
%}
$__CURRENT_GIT_STATUS
[1]%{
${
fg
[default]
}
%}
$__CURRENT_GIT_STATUS
[2]%{
${
fg
[magenta]
}
%}
$__CURRENT_GIT_STATUS
[3]%{
${
fg
[default]
}
%})"
STATUS
=
"
$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH
%{
${
reset_color
}
%}"
if
[
"
$GIT_BEHIND
"
-ne
"0"
]
;
then
STATUS
=
"
$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND
%{
${
reset_color
}
%}"
fi
if
[
"
$GIT_AHEAD
"
-ne
"0"
]
;
then
STATUS
=
"
$STATUS$ZSH_THEME_GIT_PROMPT_AHEAD$GIT_AHEAD
%{
${
reset_color
}
%}"
fi
STATUS
=
"
$STATUS$ZSH_THEME_GIT_PROMPT_SEPARATOR
"
if
[
"
$GIT_STAGED
"
-ne
"0"
]
;
then
STATUS
=
"
$STATUS$ZSH_THEME_GIT_PROMPT_STAGED$GIT_STAGED
%{
${
reset_color
}
%}"
fi
if
[
"
$GIT_CONFLICTS
"
-ne
"0"
]
;
then
STATUS
=
"
$STATUS$ZSH_THEME_GIT_PROMPT_CONFLICTS$GIT_CONFLICTS
%{
${
reset_color
}
%}"
fi
if
[
"
$GIT_CHANGED
"
-ne
"0"
]
;
then
STATUS
=
"
$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED
%{
${
reset_color
}
%}"
fi
if
[
"
$GIT_UNTRACKED
"
-ne
"0"
]
;
then
STATUS
=
"
$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED
%{
${
reset_color
}
%}"
fi
if
[
"
$GIT_CHANGED
"
-eq
"0"
]
&&
[
"
$GIT_CONFLICTS
"
-eq
"0"
]
&&
[
"
$GIT_STAGED
"
-eq
"0"
]
&&
[
"
$GIT_UNTRACKED
"
-eq
"0"
]
;
then
STATUS
=
"
$STATUS$ZSH_THEME_GIT_PROMPT_CLEAN
"
fi
STATUS
=
"
$STATUS
%{
${
reset_color
}
%}
$ZSH_THEME_GIT_PROMPT_SUFFIX
"
echo
"
$STATUS
"
fi
}
# Default values for the appearance of the prompt.
ZSH_THEME_GIT_PROMPT_PREFIX
=
"("
ZSH_THEME_GIT_PROMPT_SUFFIX
=
")"
ZSH_THEME_GIT_PROMPT_SEPARATOR
=
"|"
ZSH_THEME_GIT_PROMPT_BRANCH
=
"%{
$fg_bold
[magenta]%}"
ZSH_THEME_GIT_PROMPT_STAGED
=
"%{
$fg
[red]%}%{●%G%}"
ZSH_THEME_GIT_PROMPT_CONFLICTS
=
"%{
$fg
[red]%}%{✖%G%}"
ZSH_THEME_GIT_PROMPT_CHANGED
=
"%{
$fg
[blue]%}%{✚%G%}"
ZSH_THEME_GIT_PROMPT_BEHIND
=
"%{↓%G%}"
ZSH_THEME_GIT_PROMPT_AHEAD
=
"%{↑%G%}"
ZSH_THEME_GIT_PROMPT_UNTRACKED
=
"%{…%G%}"
ZSH_THEME_GIT_PROMPT_CLEAN
=
"%{
$fg_bold
[green]%}%{✔%G%}"
# Set the prompt.
#PROMPT='%B%m%~%b$(prompt_git_info) %# '
# for a right prompt:
#RPROMPT='%b$(prompt_git_info)'
RPROMPT
=
'$(prompt_git_info)'
RPROMPT
=
'$(git_super_status)'
plugins/git-prompt/gitstatus.py
View file @
daabe2a0
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from
subprocess
import
Popen
,
PIPE
import
re
from
__future__
import
print_function
# change those symbols to whatever you prefer
symbols
=
{
'ahead of'
:
'↑'
,
'behind'
:
'↓'
,
'staged'
:
'♦'
,
'changed'
:
'‣'
,
'untracked'
:
'…'
,
'clean'
:
'⚡'
,
'unmerged'
:
'≠'
,
'sha1'
:
':'
}
import
sys
import
re
import
shlex
from
subprocess
import
Popen
,
PIPE
,
check_output
output
,
error
=
Popen
(
[
'git'
,
'status'
],
stdout
=
PIPE
,
stderr
=
PIPE
,
universal_newlines
=
True
).
communicate
()
if
error
:
import
sys
sys
.
exit
(
0
)
lines
=
output
.
splitlines
()
def
get_tagname_or_hash
():
"""return tagname if exists else hash"""
cmd
=
'git log -1 --format="%h%d"'
output
=
check_output
(
shlex
.
split
(
cmd
)).
decode
(
'utf-8'
).
strip
()
hash_
,
tagname
=
None
,
None
# get hash
m
=
re
.
search
(
'\(.*\)$'
,
output
)
if
m
:
hash_
=
output
[:
m
.
start
()
-
1
]
# get tagname
m
=
re
.
search
(
'tag: .*[,\)]'
,
output
)
if
m
:
tagname
=
'tags/'
+
output
[
m
.
start
()
+
len
(
'tag: '
):
m
.
end
()
-
1
]
behead_re
=
re
.
compile
(
r
"^# Your branch is (ahead of|behind) '(.*)' by (\d+) commit"
)
diverge_re
=
re
.
compile
(
r
"^# and have (\d+) and (\d+) different"
)
if
tagname
:
return
tagname
elif
hash_
:
return
hash_
return
None
status
=
''
staged
=
re
.
compile
(
r
'^# Changes to be committed:$'
,
re
.
MULTILINE
)
changed
=
re
.
compile
(
r
'^# Changed but not updated:$'
,
re
.
MULTILINE
)
untracked
=
re
.
compile
(
r
'^# Untracked files:$'
,
re
.
MULTILINE
)
unmerged
=
re
.
compile
(
r
'^# Unmerged paths:$'
,
re
.
MULTILINE
)
# `git status --porcelain --branch` can collect all information
# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
po
=
Popen
([
'git'
,
'status'
,
'--porcelain'
,
'--branch'
],
stdout
=
PIPE
,
stderr
=
PIPE
)
stdout
,
sterr
=
po
.
communicate
()
if
po
.
returncode
!=
0
:
sys
.
exit
(
0
)
# Not a git repository
def
execute
(
*
command
):
out
,
err
=
Popen
(
stdout
=
PIPE
,
stderr
=
PIPE
,
*
command
).
communicate
()
if
not
err
:
nb
=
len
(
out
.
splitlines
())
# collect git status information
untracked
,
staged
,
changed
,
conflicts
=
[],
[],
[],
[]
ahead
,
behind
=
0
,
0
status
=
[(
line
[
0
],
line
[
1
],
line
[
2
:])
for
line
in
stdout
.
decode
(
'utf-8'
).
splitlines
()]
for
st
in
status
:
if
st
[
0
]
==
'#'
and
st
[
1
]
==
'#'
:
if
re
.
search
(
'Initial commit on'
,
st
[
2
]):
branch
=
st
[
2
].
split
(
' '
)[
-
1
]
elif
re
.
search
(
'no branch'
,
st
[
2
]):
# detached status
branch
=
get_tagname_or_hash
()
elif
len
(
st
[
2
].
strip
().
split
(
'...'
))
==
1
:
branch
=
st
[
2
].
strip
()
else
:
nb
=
'?'
return
nb
if
staged
.
search
(
output
):
nb
=
execute
(
[
'git'
,
'diff'
,
'--staged'
,
'--name-only'
,
'--diff-filter=ACDMRT'
])
status
+=
'%s%s'
%
(
symbols
[
'staged'
],
nb
)
if
unmerged
.
search
(
output
):
nb
=
execute
([
'git'
,
'diff'
,
'--staged'
,
'--name-only'
,
'--diff-filter=U'
])
status
+=
'%s%s'
%
(
symbols
[
'unmerged'
],
nb
)
if
changed
.
search
(
output
):
nb
=
execute
([
'git'
,
'diff'
,
'--name-only'
,
'--diff-filter=ACDMRT'
])
status
+=
'%s%s'
%
(
symbols
[
'changed'
],
nb
)
if
untracked
.
search
(
output
):
status
+=
symbols
[
'untracked'
]
if
status
==
''
:
status
=
symbols
[
'clean'
]
remote
=
''
bline
=
lines
[
0
]
if
bline
.
find
(
'Not currently on any branch'
)
!=
-
1
:
branch
=
symbols
[
'sha1'
]
+
Popen
([
'git'
,
'rev-parse'
,
'--short'
,
'HEAD'
],
stdout
=
PIPE
).
communicate
()[
0
][:
-
1
]
else
:
branch
=
bline
.
split
(
' '
)[
-
1
]
bstatusline
=
lines
[
1
]
match
=
behead_re
.
match
(
bstatusline
)
if
match
:
remote
=
symbols
[
match
.
groups
()[
0
]]
remote
+=
match
.
groups
()[
2
]
elif
lines
[
2
:]:
div_match
=
diverge_re
.
match
(
lines
[
2
])
if
div_match
:
remote
=
"{behind}{1}{ahead of}{0}"
.
format
(
*
div_match
.
groups
(),
**
symbols
)
# current and remote branch info
branch
,
rest
=
st
[
2
].
strip
().
split
(
'...'
)
if
len
(
rest
.
split
(
' '
))
==
1
:
# remote_branch = rest.split(' ')[0]
pass
else
:
# ahead or behind
divergence
=
' '
.
join
(
rest
.
split
(
' '
)[
1
:])
divergence
=
divergence
.
lstrip
(
'['
).
rstrip
(
']'
)
for
div
in
divergence
.
split
(
', '
):
if
'ahead'
in
div
:
ahead
=
int
(
div
[
len
(
'ahead '
):].
strip
())
elif
'behind'
in
div
:
behind
=
int
(
div
[
len
(
'behind '
):].
strip
())
elif
st
[
0
]
==
'?'
and
st
[
1
]
==
'?'
:
untracked
.
append
(
st
)
else
:
if
st
[
1
]
==
'M'
:
changed
.
append
(
st
)
if
st
[
0
]
==
'U'
:
conflicts
.
append
(
st
)
elif
st
[
0
]
!=
' '
:
staged
.
append
(
st
)
print
(
'
\n
'
.
join
([
branch
,
remote
,
status
]))
out
=
' '
.
join
([
branch
,
str
(
ahead
),
str
(
behind
),
str
(
len
(
staged
)),
str
(
len
(
conflicts
)),
str
(
len
(
changed
)),
str
(
len
(
untracked
)),
])
print
(
out
,
end
=
''
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment