aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xfunctions/vcs.zsh64
-rwxr-xr-xpowerlevel9k.zsh-theme2
-rwxr-xr-xtest/segments/vcs-git.spec117
3 files changed, 153 insertions, 30 deletions
diff --git a/functions/vcs.zsh b/functions/vcs.zsh
index b99e7c86..6c9bd055 100755
--- a/functions/vcs.zsh
+++ b/functions/vcs.zsh
@@ -6,18 +6,30 @@
# https://github.com/bhilburn/powerlevel9k
################################################################
-set_default POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY true
+set_default POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY false
function +vi-git-untracked() {
- # TODO: check git >= 1.7.2 - see function git_compare_version()
- local FLAGS
- FLAGS=('--porcelain')
-
- if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "false" ]]; then
- FLAGS+='--ignore-submodules=dirty'
- fi
-
- if [[ $(command git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' && \
- -n $(command git status ${FLAGS} | \grep -E '^\?\?' 2> /dev/null | tail -n1) ]]; then
+ [[ -z "${vcs_comm[gitdir]}" || "${vcs_comm[gitdir]}" == "." ]] && return
+ # If we are in a .git folder, do not check for untracked files.
+ [[ "${PWD:A}" =~ "\.git/" ]] && return
+
+ # If we are in a repos root folder, vcs_comm[gitdir] yields ".git".
+ # Inside the .git dir itself (and not a subdir of it) the variable
+ # yields ".". In any other case (either a subdirectory of .git or
+ # the repo itself), the value of vcs_comm[gitdir] is the absolute
+ # path to the .git directory.
+ # Therefore we can step up a directory, if we are inside the .git
+ # folder. And in any other case, use the parent directory of the
+ # gitdir.
+ local repoDir="."
+ # Getting the parent dir of the current dir "." is still ".", so
+ # is is safe to do this always.
+ [[ "${vcs_comm[gitdir]}" != ".git" ]] && repoDir="${vcs_comm[gitdir]:A:h}"
+ [[ "${vcs_comm[gitdir]}" == "." ]] && repoDir="${PWD:A:h}"
+
+ if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(command git submodule foreach --quiet --recursive 'command git ls-files --others --exclude-standard')" != "" ]]; then
+ hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')"
+ VCS_WORKDIR_HALF_DIRTY=true
+ elif [[ "$(command git ls-files --others --exclude-standard "${repoDir}")" != "" ]]; then
hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')"
VCS_WORKDIR_HALF_DIRTY=true
else
@@ -26,41 +38,39 @@ function +vi-git-untracked() {
}
function +vi-git-aheadbehind() {
- local ahead behind branch_name
+ local ahead behind
local -a gitstatus
- branch_name=$(command git symbolic-ref --short HEAD 2>/dev/null)
-
# for git prior to 1.7
- # ahead=$(command git rev-list origin/${branch_name}..HEAD | wc -l)
- ahead=$(command git rev-list "${branch_name}"@{upstream}..HEAD 2>/dev/null | wc -l)
+ # 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 )) && gitstatus+=( " $(print_icon 'VCS_OUTGOING_CHANGES_ICON')${ahead// /}" )
# for git prior to 1.7
- # behind=$(command git rev-list HEAD..origin/${branch_name} | wc -l)
- behind=$(command git rev-list HEAD.."${branch_name}"@{upstream} 2>/dev/null | wc -l)
+ # 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 )) && gitstatus+=( " $(print_icon 'VCS_INCOMING_CHANGES_ICON')${behind// /}" )
hook_com[misc]+=${(j::)gitstatus}
}
function +vi-git-remotebranch() {
- local remote branch_name
+ local remote
+ local branch_name="${hook_com[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)\/}
- branch_name=$(command git symbolic-ref --short HEAD 2>/dev/null)
if [[ -n "$POWERLEVEL9K_VCS_SHORTEN_LENGTH" ]] && [[ -n "$POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH" ]]; then
set_default POWERLEVEL9K_VCS_SHORTEN_DELIMITER $'\U2026'
- if [ ${#hook_com[branch]} -gt $POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH ] && [ ${#hook_com[branch]} -gt $POWERLEVEL9K_VCS_SHORTEN_LENGTH ]; then
+ if [ ${#hook_com[branch]} -gt ${POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH} ] && [ ${#hook_com[branch]} -gt ${POWERLEVEL9K_VCS_SHORTEN_LENGTH} ]; then
case "$POWERLEVEL9K_VCS_SHORTEN_STRATEGY" in
truncate_middle)
- hook_com[branch]="$(echo "${branch_name:0:$POWERLEVEL9K_VCS_SHORTEN_LENGTH}")$POWERLEVEL9K_VCS_SHORTEN_DELIMITER$(echo "${branch_name: -$POWERLEVEL9K_VCS_SHORTEN_LENGTH}")"
+ hook_com[branch]="${branch_name:0:$POWERLEVEL9K_VCS_SHORTEN_LENGTH}${POWERLEVEL9K_VCS_SHORTEN_DELIMITER}${branch_name: -$POWERLEVEL9K_VCS_SHORTEN_LENGTH}"
;;
truncate_from_right)
- hook_com[branch]="$(echo "${branch_name:0:$POWERLEVEL9K_VCS_SHORTEN_LENGTH}")$POWERLEVEL9K_VCS_SHORTEN_DELIMITER"
+ hook_com[branch]="${branch_name:0:$POWERLEVEL9K_VCS_SHORTEN_LENGTH}${POWERLEVEL9K_VCS_SHORTEN_DELIMITER}"
;;
esac
fi
@@ -104,11 +114,9 @@ function +vi-git-tagname() {
# Show count of stashed changes
# Port from https://github.com/whiteinge/dotfiles/blob/5dfd08d30f7f2749cfc60bc55564c6ea239624d9/.zsh_shouse_prompt#L268
function +vi-git-stash() {
- local -a stashes
-
- if [[ -s $(command git rev-parse --git-dir)/refs/stash ]] ; then
- stashes=$(command git stash list 2>/dev/null | wc -l)
- hook_com[misc]+=" $(print_icon 'VCS_STASH_ICON')${stashes// /}"
+ if [[ -s "${vcs_comm[gitdir]}/logs/refs/stash" ]] ; then
+ local -a stashes=( "${(@f)"$(<${vcs_comm[gitdir]}/logs/refs/stash)"}" )
+ hook_com[misc]+=" $(print_icon 'VCS_STASH_ICON')${#stashes}"
fi
}
diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme
index 41653077..7077bfc8 100755
--- a/powerlevel9k.zsh-theme
+++ b/powerlevel9k.zsh-theme
@@ -803,7 +803,7 @@ prompt_dir() {
# if we are not in "~" or "/", split the paths into an array and exclude "~"
(( ${#current_path} > 1 )) && paths=(${(s:/:)${current_path//"~\/"/}}) || paths=()
# only run the code if SHORTEN_DIR_LENGTH is set, or we are using the two strategies that don't rely on it.
- if [[ -n "$POWERLEVEL9K_SHORTEN_DIR_LENGTH" || "$POWERLEVEL9K_SHORTEN_STRATEGY" == "truncate_with_folder_marker" || "$POWERLEVEL9K_SHORTEN_STRATEGY" == "truncate_to_last" ]]; then
+ if [[ -n "$POWERLEVEL9K_SHORTEN_DIR_LENGTH" || "$POWERLEVEL9K_SHORTEN_STRATEGY" == "truncate_with_folder_marker" || "$POWERLEVEL9K_SHORTEN_STRATEGY" == "truncate_to_last" || "$POWERLEVEL9K_SHORTEN_STRATEGY" == "truncate_with_package_name" ]]; then
set_default POWERLEVEL9K_SHORTEN_DELIMITER "\u2026"
# convert delimiter from unicode to literal character, so that we can get the correct length later
local delim=$(echo -n $POWERLEVEL9K_SHORTEN_DELIMITER)
diff --git a/test/segments/vcs-git.spec b/test/segments/vcs-git.spec
index bddecf6c..17a277fb 100755
--- a/test/segments/vcs-git.spec
+++ b/test/segments/vcs-git.spec
@@ -375,4 +375,119 @@ function testShorteningCommitHashIsNotShownIfShowChangesetIsFalse() {
assertEquals "%K{002} %F{000} master %k%F{002}%f " "$(build_left_prompt)"
}
-source shunit2/shunit2 \ No newline at end of file
+function testDetectingUntrackedFilesInSubmodulesWork() {
+ local -a POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
+ POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(vcs)
+ local POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY="true"
+ unset POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND
+
+ mkdir ../submodule
+ cd ../submodule
+ git init 1>/dev/null
+ touch "i-am-tracked.txt"
+ git add . 1>/dev/null && git commit -m "Initial Commit" 1>/dev/null
+
+ local submodulePath="${PWD}"
+
+ cd -
+ git submodule add "${submodulePath}" 2>/dev/null
+ git commit -m "Add submodule" 1>/dev/null
+
+ # Go into checked-out submodule path
+ cd submodule
+ # Create untracked file
+ touch "i-am-untracked.txt"
+ cd -
+
+ source ${P9K_HOME}/powerlevel9k.zsh-theme
+
+ assertEquals "%K{002} %F{000} master ? %k%F{002}%f " "$(build_left_prompt)"
+}
+
+function testDetectinUntrackedFilesInMainRepoWithDirtySubmodulesWork() {
+ local -a POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
+ POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(vcs)
+ local POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY="true"
+ unset POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND
+
+ mkdir ../submodule
+ cd ../submodule
+ git init 1>/dev/null
+ touch "i-am-tracked.txt"
+ git add . 1>/dev/null && git commit -m "Initial Commit" 1>/dev/null
+
+ local submodulePath="${PWD}"
+
+ cd -
+ git submodule add "${submodulePath}" 2>/dev/null
+ git commit -m "Add submodule" 1>/dev/null
+
+ # Create untracked file
+ touch "i-am-untracked.txt"
+
+ source ${P9K_HOME}/powerlevel9k.zsh-theme
+
+ assertEquals "%K{002} %F{000} master ? %k%F{002}%f " "$(build_left_prompt)"
+}
+
+function testDetectingUntrackedFilesInNestedSubmodulesWork() {
+ local -a POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
+ POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(vcs)
+ local POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY="true"
+ unset POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND
+
+ local mainRepo="${PWD}"
+
+ mkdir ../submodule
+ cd ../submodule
+ git init 1>/dev/null
+ touch "i-am-tracked.txt"
+ git add . 1>/dev/null && git commit -m "Initial Commit" 1>/dev/null
+
+ local submodulePath="${PWD}"
+
+ mkdir ../subsubmodule
+ cd ../subsubmodule
+ git init 1>/dev/null
+ touch "i-am-tracked-too.txt"
+ git add . 1>/dev/null && git commit -m "Initial Commit" 1>/dev/null
+
+ local subsubmodulePath="${PWD}"
+
+ cd "${submodulePath}"
+ git submodule add "${subsubmodulePath}" 2>/dev/null
+ git commit -m "Add subsubmodule" 1>/dev/null
+ cd "${mainRepo}"
+ git submodule add "${submodulePath}" 2>/dev/null
+ git commit -m "Add submodule" 1>/dev/null
+
+ git submodule update --init --recursive 2>/dev/null
+
+ cd submodule/subsubmodule
+ # Create untracked file
+ touch "i-am-untracked.txt"
+ cd -
+
+ source ${P9K_HOME}/powerlevel9k.zsh-theme
+
+ assertEquals "%K{002} %F{000} master ? %k%F{002}%f " "$(build_left_prompt)"
+}
+
+function testDetectingUntrackedFilesInCleanSubdirectoryWorks() {
+ local -a POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
+ POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(vcs)
+ local POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY="true"
+ unset POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND
+ mkdir clean-folder
+ touch clean-folder/file.txt
+ mkdir dirty-folder
+ touch dirty-folder/file.txt
+ git add . 2>/dev/null
+ git commit -m "Initial commit" >/dev/null
+ touch dirty-folder/new-file.txt
+ cd clean-folder
+ source ${P9K_HOME}/powerlevel9k.zsh-theme
+ assertEquals "%K{002} %F{000} master ? %k%F{002}%f " "$(build_left_prompt)"
+}
+
+source shunit2/shunit2