Skip to content
This repository has been archived by the owner on Apr 24, 2020. It is now read-only.

Clarify remote name <-> remote branch #1248

Open
wants to merge 10 commits into
base: next
Choose a base branch
from
14 changes: 9 additions & 5 deletions segments/vcs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ customization is provided via:
|`P9K_VCS_CHANGESET_HASH_LENGTH`|`12`|How many characters of the hash / changeset to display in the segment.|
|`P9K_VCS_SHOW_SUBMODULE_DIRTY`|`true`|Set to `false` to not reflect submodule status in the top-level repository prompt.|
|`P9K_VCS_HIDE_TAGS`|`false`|Set to `true` to stop tags being displayed in the segment.|
|`P9K_VCS_GIT_HOOKS`|`(vcs-detect-changes vcs-icon git-untracked git-aheadbehind git-stash git-remotebranch git-gitdir git-tagname)`|Layout of the segment for git repositories.|
|`P9K_VCS_GIT_HOOKS`|`(vcs-detect-changes vcs-icon git-gather-data git-untracked git-aheadbehind git-stash git-branch-icon git-branch git-remotebranch git-gitdir git-tagname)`|Layout of the segment for git repositories.|
|`P9K_VCS_HG_HOOKS`|`(vcs-detect-changes)`|Layout of the segment for Mercurial repositories.|
|`P9K_VCS_SVN_HOOKS`|`(vcs-detect-changes svn-detect-changes)`|Layout of the segment for SVN repositories.|
|`P9K_VCS_ACTIONFORMAT_FOREGROUND`|`red`|The color of the foreground font during actions (e.g., `REBASE`).|
|`P9K_VCS_GIT_ALWAYS_SHOW_REMOTE_BRANCH`|`false`|Set to true If you would to always see the remote branch.|
|`P9K_VCS_REMOTE_DELIMITER`|`@`|This delimits the remote name from the remote branch. E.g. `master@origin`.|

### vcs symbols

Expand Down Expand Up @@ -67,8 +68,8 @@ Customizations available are:
|----------|---------------|-------------|
|`P9K_VCS_SHORTEN_LENGTH`|None|This field determines how many characters to show.|
|`P9K_VCS_SHORTEN_MIN_LENGTH`|None|This field determines minimum branch length. Branch name will be truncated if its length greater than this field.|
|`P9K_VCS_DIR_SHORTEN_STRATEGY`|None|This field determines how branch name should be truncated. See the table below for more information.|
|`P9K_DIR_SHORTEN_DELIMITER`|`...`|Delimiter to use in truncated strings. This can be any string you choose, including an empty string if you wish to have no delimiter.|
|`P9K_VCS_SHORTEN_STRATEGY`|None|This field determines how branch name should be truncated. See the table below for more information.|
|`P9K_VCS_SHORTEN_DELIMITER`|`...`|Delimiter to use in truncated strings. This can be any string you choose, including an empty string if you wish to have no delimiter.|

| Strategy Name | Description |
|---------------|-------------|
Expand All @@ -79,8 +80,8 @@ For example, if you want to truncate `1234-super_super_long_branch_name` to `123
```zsh
P9K_VCS_SHORTEN_LENGTH=4
P9K_VCS_SHORTEN_MIN_LENGTH=11
P9K_VCS_DIR_SHORTEN_STRATEGY="truncate_from_right"
P9K_VCS_DIR_SHORTEN_DELIMITER=".."
P9K_VCS_SHORTEN_STRATEGY="truncate_from_right"
P9K_VCS_SHORTEN_DELIMITER=".."
```

### Advanced features
Expand All @@ -94,9 +95,12 @@ Git hooks (`P9K_VCS_GIT_HOOKS`):
|--------------------|----------------------------------------------------|
| vcs-detect-changes | General check for changed files and responsible for selecting a proper icon according to the remote url. |
| vcs-icon | Detects the icon base on the remote url. E.g. shows the Github icon for a repository cloned from Github. If no remote given, it uses the default icon from `P9K_VCS_GIT_ICON`. |
| git-gather-data | Internal hook, that saves the branch name in an internal array. Necessary for showing the local/remote branch. |
| git-untracked | Check for untracked files. |
| git-aheadbehind | Check for commits ahead/behind the repo. This does not request changes from the remote repo. Only interacts with the local repo. |
| git-stash | Check for stashes. |
| git-branch-icon | Shows an icon for the branch. |
| git-branch | Display the local branch and truncates it, if configured. |
| git-remotebranch | Checks the remote branch, and displays it, if it differs from local branch name. |
| git-gitdir | Responsible to find out if we are in a clobbered checkout. |
| git-tagname | Get the tagname, if we are on a tag. |
Expand Down
57 changes: 36 additions & 21 deletions segments/vcs/vcs.p9k
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,20 @@
p9k::set_default P9K_VCS_ACTIONFORMAT_FOREGROUND "red"
p9k::set_default P9K_VCS_HIDE_TAGS false
p9k::set_default P9K_VCS_INTERNAL_HASH_LENGTH "8" # Default: Just display the first 8 characters of our changeset-ID.
p9k::set_default P9K_VCS_DIR_SHORTEN_DELIMITER $'\U2026'
p9k::set_default P9K_VCS_SHORTEN_DELIMITER $'\u2026'
p9k::set_default P9K_VCS_REMOTE_DELIMITER ":"
p9k::set_default P9K_VCS_SHOW_SUBMODULE_DIRTY true
p9k::set_default P9K_VCS_GIT_ALWAYS_SHOW_REMOTE_BRANCH false
p9k::set_default P9K_VCS_SHOW_CHANGESET false
}

typeset -gAH __P9K_VCS_DATA
function +vi-git-gather-data() {
__P9K_VCS_DATA[branch]="${hook_com[branch]//\%/%%}"
# Reset the branch name for a fresh start.
hook_com[branch]=''
}

function +vi-git-untracked() {
[[ -z "${vcs_comm[gitdir]}" || "${vcs_comm[gitdir]}" == "." ]] && return

Expand All @@ -168,50 +176,57 @@ function +vi-git-aheadbehind() {
local -a gitstatus

# for git prior to 1.7
# ahead=$(command git rev-list origin/${hook_com[branch]}..HEAD | wc -l)
ahead=$(command git rev-list --count "${hook_com[branch]}"@{upstream}..HEAD 2>/dev/null)
# ahead=$(command git rev-list origin/${__P9K_VCS_DATA[branch]}..HEAD | wc -l)
ahead=$(command git rev-list --count "${__P9K_VCS_DATA[branch]}"@{upstream}..HEAD 2>/dev/null)
(( ahead )) && gitstatus+=( " ${__P9K_ICONS[VCS_OUTGOING_CHANGES]}${ahead// /}" )

# for git prior to 1.7
# behind=$(command git rev-list HEAD..origin/${hook_com[branch]} | wc -l)
behind=$(command git rev-list --count HEAD.."${hook_com[branch]}"@{upstream} 2>/dev/null)
# behind=$(command git rev-list HEAD..origin/${__P9K_VCS_DATA[branch]} | wc -l)
behind=$(command git rev-list --count HEAD.."${__P9K_VCS_DATA[branch]}"@{upstream} 2>/dev/null)
(( behind )) && gitstatus+=( " ${__P9K_ICONS[VCS_INCOMING_CHANGES]}${behind// /}" )

hook_com[misc]+=${(j::)gitstatus}
}

function +vi-git-remotebranch() {
local remote
local branch_name="${hook_com[branch]}"
function +vi-git-branch-icon() {
[[ -n "${__P9K_VCS_DATA[branch]}" ]] && hook_com[branch]+="${__P9K_ICONS[VCS_BRANCH]}"
}

# Are we on a remote-tracking branch?
remote=${$(command git rev-parse --verify HEAD@{upstream} --symbolic-full-name 2>/dev/null)/refs\/(remotes|heads)\/}
function +vi-git-branch() {
local branch="${__P9K_VCS_DATA[branch]}"

# Truncate the branch name, if it is too long
if [[ -n "$P9K_VCS_SHORTEN_LENGTH" ]] && [[ -n "$P9K_VCS_SHORTEN_MIN_LENGTH" ]]; then
p9k::set_default P9K_VCS_SHORTEN_DELIMITER $'\u2026'

if [ ${#hook_com[branch]} -gt ${P9K_VCS_SHORTEN_MIN_LENGTH} ] && [ ${#hook_com[branch]} -gt ${P9K_VCS_SHORTEN_LENGTH} ]; then
if [ ${#__P9K_VCS_DATA[branch]} -gt ${P9K_VCS_SHORTEN_MIN_LENGTH} ] && [ ${#__P9K_VCS_DATA[branch]} -gt ${P9K_VCS_SHORTEN_LENGTH} ]; then
case "$P9K_VCS_SHORTEN_STRATEGY" in
truncate_middle)
hook_com[branch]="${branch_name:0:$P9K_VCS_SHORTEN_LENGTH}${P9K_VCS_SHORTEN_DELIMITER}${branch_name: -$P9K_VCS_SHORTEN_LENGTH}"
branch="${__P9K_VCS_DATA[branch]:0:$P9K_VCS_SHORTEN_LENGTH}${P9K_VCS_SHORTEN_DELIMITER}${__P9K_VCS_DATA[branch]: -$P9K_VCS_SHORTEN_LENGTH}"
;;
truncate_from_right)
hook_com[branch]="${branch_name:0:$P9K_VCS_SHORTEN_LENGTH}${P9K_VCS_SHORTEN_DELIMITER}"
branch="${__P9K_VCS_DATA[branch]:0:$P9K_VCS_SHORTEN_LENGTH}${P9K_VCS_SHORTEN_DELIMITER}"
;;
esac
fi
fi

hook_com[branch]="${__P9K_ICONS[VCS_BRANCH]}${hook_com[branch]//\%/%%}"
# Always show the remote
#if [[ -n ${remote} ]] ; then
hook_com[branch]+="${branch}"
}

function +vi-git-remotebranch() {
# Are we on a remote-tracking branch?
local remote=${$(command git rev-parse --verify HEAD@{upstream} --symbolic-full-name 2>/dev/null)/refs\/(remotes|heads)\/}

# Only show the remote if it differs from the local
if [[ -n ${remote} \
&& ( \
"${P9K_VCS_GIT_ALWAYS_SHOW_REMOTE_BRANCH}" == 'true' \
|| "${remote#*/}" != "${branch_name#heads/}" \
|| "${remote#*/}" != "${__P9K_VCS_DATA[branch]#heads/}" \
) ]]; then
hook_com[branch]+="${__P9K_ICONS[VCS_REMOTE_BRANCH]}${${remote// /}//\%/%%}"
local remote_name=$(command git config branch.${__P9K_VCS_DATA[branch]#heads/}.remote)
# Remote Branch is the remote branch name, without the remote name.
# Additionally, remove trailing whitespace and escape percent signs.
local remote_branch=${${${remote#${remote_name}/}// /}//\%/%%}
hook_com[branch]+="${__P9K_ICONS[VCS_REMOTE_BRANCH]}${remote_name}${P9K_VCS_REMOTE_DELIMITER}${remote_branch}"
fi
}

Expand Down Expand Up @@ -389,7 +404,7 @@ __p9k_vcs_init() {
# Hooks are places in vcs_info where you can run your own code. That code can communicate with the code that called it and through that, change the system’s behaviour.
# For configuration, hooks change the style context:
# :vcs_info:vcs-string+hook-name:user-context:repo-root-name
p9k::defined P9K_VCS_GIT_HOOKS || P9K_VCS_GIT_HOOKS=(vcs-detect-changes vcs-icon git-untracked git-aheadbehind git-stash git-remotebranch git-gitdir git-tagname)
p9k::defined P9K_VCS_GIT_HOOKS || P9K_VCS_GIT_HOOKS=(vcs-detect-changes vcs-icon git-gather-data git-untracked git-aheadbehind git-stash git-branch-icon git-branch git-remotebranch git-gitdir git-tagname)
zstyle ':vcs_info:git*+set-message:*' hooks ${P9K_VCS_GIT_HOOKS}
p9k::defined P9K_VCS_HG_HOOKS || P9K_VCS_HG_HOOKS=(vcs-detect-changes vcs-icon hg-branch)
zstyle ':vcs_info:hg*+set-message:*' hooks ${P9K_VCS_HG_HOOKS}
Expand Down
12 changes: 8 additions & 4 deletions segments/vcs/vcs_git.spec
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ function testRemoteBranchNameIdenticalToTag() {

function testAlwaysShowRemoteBranch() {
P9K_LEFT_PROMPT_ELEMENTS=(vcs)
local P9K_VCS_GIT_ALWAYS_SHOW_REMOTE_BRANCH='true'
local P9K_VCS_GIT_ALWAYS_SHOW_REMOTE_BRANCH='false'
local P9K_VCS_HIDE_TAGS='true'
source "${P9K_HOME}/segments/vcs/vcs.p9k"

Expand All @@ -426,10 +426,14 @@ function testAlwaysShowRemoteBranch() {
git clone . ../vcs-test2 1>/dev/null 2>&1
cd ../vcs-test2

assertEquals "%K{002} %F{000} master→origin/master %k%F{002}%f " "$(__p9k_build_left_prompt)"

local P9K_VCS_GIT_ALWAYS_SHOW_REMOTE_BRANCH='false'
assertEquals "%K{002} %F{000} master %k%F{002}%f " "$(__p9k_build_left_prompt)"

git remote rename origin some/remote
local P9K_VCS_GIT_ALWAYS_SHOW_REMOTE_BRANCH='true'
assertEquals "%K{002} %F{000} master→some/remote:master %k%F{002}%f " "$(__p9k_build_left_prompt)"

git branch -m master new/ref/master
assertEquals "%K{002} %F{000} new/ref/master→some/remote:master %k%F{002}%f " "$(__p9k_build_left_prompt)"
}

function testGitDirClobber() {
Expand Down