Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Git plugin: Replace calls to git status with porcelain commands #40

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 48 additions & 74 deletions plugins/git/functions/git-info
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ function git-info() {
local git_info_var
local -A git_info_vars
local status_cmd
local remote_cmd
local upstream_diff_cmd
local ignore_submodule
local ignore_submodule_when

Expand Down Expand Up @@ -204,7 +206,11 @@ function git-info() {
_git_info_executing=true

# Use short status for easy parsing.
status_cmd='git status --short --branch'
status_cmd='git status --porcelain'
# Get remote's name.
remote_cmd='git rev-parse --verify HEAD@{upstream} --symbolic-full-name'
# Get commits count between the local and the remote branch
upstream_diff_cmd='git rev-list --count --left-right @{upstream}...HEAD'

# Ignore submodule status.
zstyle -b \
Expand All @@ -231,88 +237,56 @@ function git-info() {
zformat -f stashed_formatted "$stashed_format" "S:$stashed"
fi

while IFS=$'\n' read line; do
(( line_number++ ))

if (( line_number == 1 )) && [[ "$line" == *'(no branch)'* ]]; then
# Get action.
action="$(_git-action)"
# Format action.
action="$(_git-action)"
if [[ -n "$action" ]]; then
zstyle -s ':omz:plugin:git:prompt' action 'action_format'
zformat -f action_formatted "$action_format" "s:$action"
fi

# Format action.
if [[ -n "$action" ]]; then
zstyle -s ':omz:plugin:git:prompt' action 'action_format'
zformat -f action_formatted "$action_format" "s:$action"
fi
elif (( line_number == 1 )) \
&& [[ "$line" == (#b)'## Initial commit on '(?##) ]];
then
branch="$match[1]"
elif (( line_number == 1 )); then
# Split the line into an array for parsing.
branch_info=(${(s: :)line})

# Match: master...origin/master
if [[ "$branch_info[2]" == (#b)(?##)...(?##/?##) ]]; then
branch="$match[1]"
remote="$match[2]"

# Match: [ahead or [behind
if [[ "$branch_info[3]" == (#b)\[(ahead|behind) ]]; then
ahead_or_behind="$match[1]"
if [[ "$ahead_or_behind" == 'behind' ]]; then
# Extract digits: 10]
behind="${branch_info[4]%\]}"
else
# Extract digits: 10] or 10,
ahead="${branch_info[4]%[,\]]}"
# Extract digits: 10]
behind="${branch_info[6]%\]}"
fi
fi
# Match: master
elif [[ "$branch_info[2]" == (#b)(?##) ]]; then
branch="$match[1]"
fi
else
# Count added, deleted, modified, renamed, unmerged, untracked, dirty.
# T (type change) is undocumented, see http://git.io/FnpMGw.
# For a table of scenarii, see http://i.imgur.com/2YLu1.png.
[[ "$line" == ([ACDMT][\ MT]|[ACMT]D)\ * ]] && (( added++ ))
[[ "$line" == [\ ACMRT]D\ * ]] && (( deleted++ ))
[[ "$line" == ?[MT]\ * ]] && (( modified++ ))
[[ "$line" == R?\ * ]] && (( renamed++ ))
[[ "$line" == (AA|DD|U?|?U)\ * ]] && (( unmerged++ ))
[[ "$line" == \?\?\ * ]] && (( untracked++ ))
(( dirty++ ))
fi
done < <("${(z)status_cmd}" 2>/dev/null)
# Get current status.
while IFS=$'\n' read line; do
# Count added, deleted, modified, renamed, unmerged, untracked, dirty.
# T (type change) is undocumented, see http://git.io/FnpMGw.
# For a table of scenarii, see http://i.imgur.com/2YLu1.png.
[[ "$line" == ([ACDMT][\ MT]|[ACMT]D)\ * ]] && (( added++ ))
[[ "$line" == [\ ACMRT]D\ * ]] && (( deleted++ ))
[[ "$line" == ?[MT]\ * ]] && (( modified++ ))
[[ "$line" == R?\ * ]] && (( renamed++ ))
[[ "$line" == (AA|DD|U?|?U)\ * ]] && (( unmerged++ ))
[[ "$line" == \?\?\ * ]] && (( untracked++ ))
(( dirty++ ))
done < <(${(z)status_cmd} 2>/dev/null)

# Format branch.
branch=${$(git symbolic-ref -q HEAD)##refs/heads/}
if [[ -n "$branch" ]]; then
zstyle -s ':omz:plugin:git:prompt' branch 'branch_format'
zformat -f branch_formatted "$branch_format" "b:$branch"

# Format remote.
if [[ -z "$remote" ]]; then
remote="${$( \
git rev-parse \
--verify ${branch}@{upstream} \
--symbolic-full-name 2>/dev/null)#refs/remotes/}"
fi
zstyle -s ':omz:plugin:git:prompt' remote 'remote_format'
zformat -f remote_formatted "$remote_format" "R:$remote"
fi

# Format ahead.
if [[ -n "$ahead" ]]; then
zstyle -s ':omz:plugin:git:prompt' ahead 'ahead_format'
zformat -f ahead_formatted "$ahead_format" "A:$ahead"
fi
remote=${$(${(z)remote_cmd} 2>/dev/null)##refs/remotes/}
if [[ -n "$remote" ]]; then
zstyle -s ':omz:plugin:git:prompt' remote 'remote_format'
zformat -f remote_formatted "$remote_format" "R:$remote"

# Get difference with remote.
upstream_diff=$(${(z)upstream_diff_cmd} 2>/dev/null)

# Format ahead.
ahead=$upstream_diff[(w)2]
if [[ $ahead > 0 ]]; then
zstyle -s ':omz:plugin:git:prompt' ahead 'ahead_format'
zformat -f ahead_formatted "$ahead_format" "A:$ahead"
fi

# Format behind.
if [[ -n "$behind" ]]; then
zstyle -s ':omz:plugin:git:prompt' behind 'behind_format'
zformat -f behind_formatted "$behind_format" "B:$behind"
# Format behind.
behind=$upstream_diff[(w)1]
if [[ $behind > 0 ]]; then
zstyle -s ':omz:plugin:git:prompt' behind 'behind_format'
zformat -f behind_formatted "$behind_format" "B:$behind"
fi
fi
fi

# Format added.
Expand Down