From cd0ad84b0100ca14ddb30d93a53094c0e9343e40 Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Sat, 3 Nov 2018 03:06:49 +0100 Subject: [PATCH 1/7] Get rid of wc dependency when showing ahead/behind info --- functions/vcs.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index b99e7c86..1478e0e2 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -33,12 +33,12 @@ function +vi-git-aheadbehind() { # 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 --count "${branch_name}"@{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 --count HEAD.."${branch_name}"@{upstream} 2>/dev/null) (( behind )) && gitstatus+=( " $(print_icon 'VCS_INCOMING_CHANGES_ICON')${behind// /}" ) hook_com[misc]+=${(j::)gitstatus} From fea5f616d17b11446a48327b6719180adf577425 Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Sat, 3 Nov 2018 03:08:32 +0100 Subject: [PATCH 2/7] Get branch name from VCS_INFO subsystem when collecting ahead/behind info --- functions/vcs.zsh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index 1478e0e2..50a77d49 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -26,19 +26,17 @@ 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 --count "${branch_name}"@{upstream}..HEAD 2>/dev/null) + # 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 --count HEAD.."${branch_name}"@{upstream} 2>/dev/null) + # 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} From 9a67ca5bc37a0dc6a397e59fb89b8565fcb468c4 Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Sat, 3 Nov 2018 03:10:53 +0100 Subject: [PATCH 3/7] Get branch name from VCS_INFO subsystem when collecting remote branch --- functions/vcs.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index 50a77d49..23b2b661 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -43,11 +43,11 @@ function +vi-git-aheadbehind() { } 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' From d07507c1ebf60d1d71ba491d0358b312e3e44807 Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Sat, 3 Nov 2018 03:11:51 +0100 Subject: [PATCH 4/7] Make use of git dir determined by VCS_INFO subsystem instead of determine the git dir manually. --- functions/vcs.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index 23b2b661..cfc62a6d 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -104,7 +104,7 @@ function +vi-git-tagname() { function +vi-git-stash() { local -a stashes - if [[ -s $(command git rev-parse --git-dir)/refs/stash ]] ; then + if [[ -s "${vcs_comm[gitdir]}/refs/stash" ]] ; then stashes=$(command git stash list 2>/dev/null | wc -l) hook_com[misc]+=" $(print_icon 'VCS_STASH_ICON')${stashes// /}" fi From 44b4b669258f0854e17e439337a8a8fdf1dea5df Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Sat, 3 Nov 2018 03:21:47 +0100 Subject: [PATCH 5/7] Speedup VCS segment Now the untracked files are detected via `git ls-files`, which is much faster than `git status`. Additionally, we flipped the default for checking submodules. They are now NOT checked by default, as most users probably do not use git submodules. --- functions/vcs.zsh | 16 +++++----------- test/segments/vcs-git.spec | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index cfc62a6d..6cc467d7 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -6,18 +6,12 @@ # 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 + if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(command git submodule foreach '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)" != "" ]]; then hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" VCS_WORKDIR_HALF_DIRTY=true else diff --git a/test/segments/vcs-git.spec b/test/segments/vcs-git.spec index bddecf6c..21bdc892 100755 --- a/test/segments/vcs-git.spec +++ b/test/segments/vcs-git.spec @@ -375,4 +375,29 @@ function testShorteningCommitHashIsNotShownIfShowChangesetIsFalse() { assertEquals "%K{002} %F{000} master %k%F{002}%f " "$(build_left_prompt)" } +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 + # Create untracked file + touch "i-am-untracked.txt" + + local submodulePath="${PWD}" + + cd - + git submodule add "${submodulePath}" 2>/dev/null + git commit -m "Add submodule" 1>/dev/null + + source ${P9K_HOME}/powerlevel9k.zsh-theme + + assertEquals "%K{002} %F{000} master ? %k%F{002}%f " "$(build_left_prompt)" +} + source shunit2/shunit2 \ No newline at end of file From c3f9d04354b53dd88bcaff790fca371b810054d6 Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Sat, 3 Nov 2018 03:23:23 +0100 Subject: [PATCH 6/7] When checking for untracked or modified files, take submodules into account --- functions/vcs.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/vcs.zsh b/functions/vcs.zsh index 6cc467d7..3b3b938f 100755 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -8,7 +8,7 @@ set_default POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY false function +vi-git-untracked() { - if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(command git submodule foreach 'git ls-files --others --exclude-standard')" != "" ]]; then + if [[ "$POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY" == "true" && "$(command git submodule foreach --quiet --recursive '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)" != "" ]]; then From 9d84e6fb6a87748b48056cab46f505fa32cbbfa1 Mon Sep 17 00:00:00 2001 From: Dominik Ritter Date: Sat, 3 Nov 2018 03:45:05 +0100 Subject: [PATCH 7/7] Add tests for complex git submodule scenarios --- test/segments/vcs-git.spec | 77 +++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/test/segments/vcs-git.spec b/test/segments/vcs-git.spec index 21bdc892..fed1df19 100755 --- a/test/segments/vcs-git.spec +++ b/test/segments/vcs-git.spec @@ -386,8 +386,6 @@ function testDetectingUntrackedFilesInSubmodulesWork() { git init 1>/dev/null touch "i-am-tracked.txt" git add . 1>/dev/null && git commit -m "Initial Commit" 1>/dev/null - # Create untracked file - touch "i-am-untracked.txt" local submodulePath="${PWD}" @@ -395,6 +393,81 @@ function testDetectingUntrackedFilesInSubmodulesWork() { 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)"